about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-13 10:27:30 +0000
committerbors <bors@rust-lang.org>2025-03-13 10:27:30 +0000
commita2aba0578ba440130d2ee213fc9dfdaa7095bdb5 (patch)
tree58d1d86e73a6dab6d4eefb07876db427ce9834af
parent961351c76c812e3aeb65bfb542742500a6436aed (diff)
parent3bfce83cb2e880a7f2a601326a56a57abaf6bd8c (diff)
downloadrust-a2aba0578ba440130d2ee213fc9dfdaa7095bdb5.tar.gz
rust-a2aba0578ba440130d2ee213fc9dfdaa7095bdb5.zip
Auto merge of #138448 - matthiaskrgr:rollup-3onhkse, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #126856 (remove deprecated tool `rls`)
 - #133981 (rustdoc-json: Refractor and document Id's)
 - #136842 (Add libstd support for Trusty targets)
 - #137355 (Implement `read_buf` and vectored read/write for SGX stdio)
 - #138162 (Update the standard library to Rust 2024)
 - #138273 (metadata: Ignore sysroot when doing the manual native lib search in rustc)
 - #138346 (naked functions: on windows emit `.endef` without the symbol name)
 - #138370 (Simulate OOM for the `try_oom_error` test)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/naked_asm.rs2
-rw-r--r--compiler/rustc_metadata/src/lib.rs4
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs63
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/core/Cargo.toml2
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/panic_abort/Cargo.toml2
-rw-r--r--library/panic_unwind/Cargo.toml2
-rw-r--r--library/proc_macro/Cargo.toml2
-rw-r--r--library/profiler_builtins/Cargo.toml2
-rw-r--r--library/rustc-std-workspace-alloc/Cargo.toml2
-rw-r--r--library/rustc-std-workspace-core/Cargo.toml2
-rw-r--r--library/rustc-std-workspace-std/Cargo.toml2
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/build.rs1
-rw-r--r--library/std/src/fs.rs3
-rw-r--r--library/std/src/io/tests.rs16
-rw-r--r--library/std/src/keyword_docs.rs2
-rw-r--r--library/std/src/net/tcp.rs3
-rw-r--r--library/std/src/net/udp.rs3
-rw-r--r--library/std/src/os/fd/mod.rs1
-rw-r--r--library/std/src/os/fd/owned.rs28
-rw-r--r--library/std/src/os/fd/raw.rs10
-rw-r--r--library/std/src/os/mod.rs4
-rw-r--r--library/std/src/os/trusty/io/mod.rs4
-rw-r--r--library/std/src/os/trusty/mod.rs3
-rw-r--r--library/std/src/os/windows/process.rs2
-rw-r--r--library/std/src/process.rs3
-rw-r--r--library/std/src/sys/alloc/mod.rs1
-rw-r--r--library/std/src/sys/pal/mod.rs3
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs64
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/mod.rs17
-rw-r--r--library/std/src/sys/pal/sgx/fd.rs2
-rw-r--r--library/std/src/sys/pal/trusty/mod.rs21
-rw-r--r--library/std/src/sys/random/mod.rs3
-rw-r--r--library/std/src/sys/random/trusty.rs7
-rw-r--r--library/std/src/sys/stdio/mod.rs3
-rw-r--r--library/std/src/sys/stdio/sgx.rs33
-rw-r--r--library/std/src/sys/stdio/trusty.rs81
-rw-r--r--library/std/src/sys/thread_local/mod.rs2
-rw-r--r--library/sysroot/Cargo.toml2
-rw-r--r--library/test/Cargo.toml2
-rw-r--r--library/unwind/Cargo.toml2
-rw-r--r--library/windows_targets/Cargo.toml2
-rw-r--r--library/windows_targets/src/lib.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs43
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs2
-rw-r--r--src/bootstrap/src/core/builder/mod.rs4
-rw-r--r--src/bootstrap/src/lib.rs2
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/tarball.rs3
-rw-r--r--src/doc/rustc/src/platform-support.md6
-rw-r--r--src/doc/rustc/src/platform-support/trusty.md6
-rw-r--r--src/librustdoc/json/conversions.rs66
-rw-r--r--src/librustdoc/json/ids.rs122
-rw-r--r--src/librustdoc/json/mod.rs12
-rw-r--r--src/tools/build-manifest/src/main.rs2
-rw-r--r--src/tools/build-manifest/src/versions.rs3
-rw-r--r--src/tools/rls/Cargo.toml8
-rw-r--r--src/tools/rls/README.md6
-rw-r--r--src/tools/rls/src/main.rs102
-rw-r--r--src/tools/tidy/src/walk.rs2
-rw-r--r--tests/codegen/naked-fn/naked-functions.rs72
-rw-r--r--tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff10
-rw-r--r--tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff6
-rw-r--r--tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff6
-rw-r--r--tests/run-make/core-no-fp-fmt-parse/rmake.rs2
-rw-r--r--tests/ui/macros/std-2024-macros.rs13
74 files changed, 560 insertions, 406 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7625b38401d..942f8f43935 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3046,13 +3046,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rls"
-version = "2.0.0"
-dependencies = [
- "serde_json",
-]
-
-[[package]]
 name = "run_make_support"
 version = "0.2.0"
 dependencies = [
diff --git a/Cargo.toml b/Cargo.toml
index 20a43aaaeeb..915ec2e00ca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,6 @@ members = [
   "src/tools/remote-test-server",
   "src/tools/rust-installer",
   "src/tools/rustdoc",
-  "src/tools/rls",
   "src/tools/rustfmt",
   "src/tools/miri",
   "src/tools/miri/cargo-miri",
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 7d9971c021d..0ac0ad46295 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -22,7 +22,9 @@ use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_macros::LintDiagnostic;
 use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
-use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
+use rustc_metadata::{
+    NativeLibSearchFallback, find_native_static_library, walk_native_lib_search_dirs,
+};
 use rustc_middle::bug;
 use rustc_middle::lint::lint_level;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -2129,19 +2131,15 @@ fn add_library_search_dirs(
         return;
     }
 
-    walk_native_lib_search_dirs(
-        sess,
-        self_contained_components,
-        apple_sdk_root,
-        |dir, is_framework| {
-            if is_framework {
-                cmd.framework_path(dir);
-            } else {
-                cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
-            }
-            ControlFlow::<()>::Continue(())
-        },
-    );
+    let fallback = Some(NativeLibSearchFallback { self_contained_components, apple_sdk_root });
+    walk_native_lib_search_dirs(sess, fallback, |dir, is_framework| {
+        if is_framework {
+            cmd.framework_path(dir);
+        } else {
+            cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
+        }
+        ControlFlow::<()>::Continue(())
+    });
 }
 
 /// Add options making relocation sections in the produced ELF files read-only
diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
index 96d1ab018f6..676cd6d2477 100644
--- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
@@ -245,7 +245,7 @@ fn prefix_and_suffix<'tcx>(
             writeln!(begin, ".def {asm_name}").unwrap();
             writeln!(begin, ".scl 2").unwrap();
             writeln!(begin, ".type 32").unwrap();
-            writeln!(begin, ".endef {asm_name}").unwrap();
+            writeln!(begin, ".endef").unwrap();
             writeln!(begin, "{asm_name}:").unwrap();
 
             writeln!(end).unwrap();
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 634c82fd1d5..028d5c8b609 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -35,8 +35,8 @@ pub mod locator;
 pub use creader::{DylibError, load_symbol_from_dylib};
 pub use fs::{METADATA_FILENAME, emit_wrapper_file};
 pub use native_libs::{
-    find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library,
-    walk_native_lib_search_dirs,
+    NativeLibSearchFallback, find_native_static_library, try_find_native_dynamic_library,
+    try_find_native_static_library, walk_native_lib_search_dirs,
 };
 pub use rmeta::{EncodedMetadata, METADATA_HEADER, encode_metadata, rendered_const};
 
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index b96921a63f3..1671b7e06b0 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -21,10 +21,17 @@ use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents};
 
 use crate::{errors, fluent_generated};
 
+/// The fallback directories are passed to linker, but not used when rustc does the search,
+/// because in the latter case the set of fallback directories cannot always be determined
+/// consistently at the moment.
+pub struct NativeLibSearchFallback<'a> {
+    pub self_contained_components: LinkSelfContainedComponents,
+    pub apple_sdk_root: Option<&'a Path>,
+}
+
 pub fn walk_native_lib_search_dirs<R>(
     sess: &Session,
-    self_contained_components: LinkSelfContainedComponents,
-    apple_sdk_root: Option<&Path>,
+    fallback: Option<NativeLibSearchFallback<'_>>,
     mut f: impl FnMut(&Path, bool /*is_framework*/) -> ControlFlow<R>,
 ) -> ControlFlow<R> {
     // Library search paths explicitly supplied by user (`-L` on the command line).
@@ -38,6 +45,11 @@ pub fn walk_native_lib_search_dirs<R>(
         }
     }
 
+    let Some(NativeLibSearchFallback { self_contained_components, apple_sdk_root }) = fallback
+    else {
+        return ControlFlow::Continue(());
+    };
+
     // The toolchain ships some native library components and self-contained linking was enabled.
     // Add the self-contained library directory to search paths.
     if self_contained_components.intersects(
@@ -93,23 +105,17 @@ pub fn try_find_native_static_library(
         if os == unix { vec![os] } else { vec![os, unix] }
     };
 
-    // FIXME: Account for self-contained linking settings and Apple SDK.
-    walk_native_lib_search_dirs(
-        sess,
-        LinkSelfContainedComponents::empty(),
-        None,
-        |dir, is_framework| {
-            if !is_framework {
-                for (prefix, suffix) in &formats {
-                    let test = dir.join(format!("{prefix}{name}{suffix}"));
-                    if test.exists() {
-                        return ControlFlow::Break(test);
-                    }
+    walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
+        if !is_framework {
+            for (prefix, suffix) in &formats {
+                let test = dir.join(format!("{prefix}{name}{suffix}"));
+                if test.exists() {
+                    return ControlFlow::Break(test);
                 }
             }
-            ControlFlow::Continue(())
-        },
-    )
+        }
+        ControlFlow::Continue(())
+    })
     .break_value()
 }
 
@@ -132,22 +138,17 @@ pub fn try_find_native_dynamic_library(
         vec![os, meson, mingw]
     };
 
-    walk_native_lib_search_dirs(
-        sess,
-        LinkSelfContainedComponents::empty(),
-        None,
-        |dir, is_framework| {
-            if !is_framework {
-                for (prefix, suffix) in &formats {
-                    let test = dir.join(format!("{prefix}{name}{suffix}"));
-                    if test.exists() {
-                        return ControlFlow::Break(test);
-                    }
+    walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
+        if !is_framework {
+            for (prefix, suffix) in &formats {
+                let test = dir.join(format!("{prefix}{name}{suffix}"));
+                if test.exists() {
+                    return ControlFlow::Break(test);
                 }
             }
-            ControlFlow::Continue(())
-        },
-    )
+        }
+        ControlFlow::Continue(())
+    })
     .break_value()
 }
 
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index dbdf292433b..8d0253bd29a 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -8,7 +8,7 @@ repository = "https://github.com/rust-lang/rust.git"
 description = "The Rust core allocation and collections library"
 autotests = false
 autobenches = false
-edition = "2021"
+edition = "2024"
 
 [lib]
 test = false
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index edde8153aa1..b60826ee4e6 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -9,7 +9,7 @@ autobenches = false
 # If you update this, be sure to update it in a bunch of other places too!
 # As of 2024, it was src/tools/opt-dist, the core-no-fp-fmt-parse test and
 # the version of the prelude imported in core/lib.rs.
-edition = "2021"
+edition = "2024"
 
 [lib]
 test = false
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 987fa93d598..6e058069756 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -226,7 +226,7 @@ extern crate self as core;
 
 #[prelude_import]
 #[allow(unused)]
-use prelude::rust_2021::*;
+use prelude::rust_2024::*;
 
 #[cfg(not(test))] // See #65860
 #[macro_use]
diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml
index a9d1f53761c..6f43ac4809a 100644
--- a/library/panic_abort/Cargo.toml
+++ b/library/panic_abort/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
 description = "Implementation of Rust panics via process aborts"
-edition = "2021"
+edition = "2024"
 
 [lib]
 test = false
diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml
index c2abb79192e..d176434e06b 100644
--- a/library/panic_unwind/Cargo.toml
+++ b/library/panic_unwind/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
 description = "Implementation of Rust panics via stack unwinding"
-edition = "2021"
+edition = "2024"
 
 [lib]
 test = false
diff --git a/library/proc_macro/Cargo.toml b/library/proc_macro/Cargo.toml
index e54a50aa15c..72cb4e4166f 100644
--- a/library/proc_macro/Cargo.toml
+++ b/library/proc_macro/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "proc_macro"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 std = { path = "../std" }
diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml
index 230e8051602..e075a38daea 100644
--- a/library/profiler_builtins/Cargo.toml
+++ b/library/profiler_builtins/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "profiler_builtins"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 
 [lib]
 test = false
diff --git a/library/rustc-std-workspace-alloc/Cargo.toml b/library/rustc-std-workspace-alloc/Cargo.toml
index 049ca3e46b5..5a177808d1b 100644
--- a/library/rustc-std-workspace-alloc/Cargo.toml
+++ b/library/rustc-std-workspace-alloc/Cargo.toml
@@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
 """
-edition = "2021"
+edition = "2024"
 
 [lib]
 path = "lib.rs"
diff --git a/library/rustc-std-workspace-core/Cargo.toml b/library/rustc-std-workspace-core/Cargo.toml
index ff5cfcbd641..9315c08a4d1 100644
--- a/library/rustc-std-workspace-core/Cargo.toml
+++ b/library/rustc-std-workspace-core/Cargo.toml
@@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
 """
-edition = "2021"
+edition = "2024"
 
 [lib]
 path = "lib.rs"
diff --git a/library/rustc-std-workspace-std/Cargo.toml b/library/rustc-std-workspace-std/Cargo.toml
index 3a1dc2a02b5..f70994e1f88 100644
--- a/library/rustc-std-workspace-std/Cargo.toml
+++ b/library/rustc-std-workspace-std/Cargo.toml
@@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
 """
-edition = "2021"
+edition = "2024"
 
 [lib]
 path = "lib.rs"
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index f7379c413f1..95fe682e436 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.0.0"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
 description = "The Rust Standard Library"
-edition = "2021"
+edition = "2024"
 autobenches = false
 
 [lib]
diff --git a/library/std/build.rs b/library/std/build.rs
index cedfd7406a1..a0cfbc4685e 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -42,6 +42,7 @@ fn main() {
         || target_os == "fuchsia"
         || (target_vendor == "fortanix" && target_env == "sgx")
         || target_os == "hermit"
+        || target_os == "trusty"
         || target_os == "l4re"
         || target_os == "redox"
         || target_os == "haiku"
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 46b5860123f..f9a360585e8 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -14,7 +14,8 @@
         target_os = "emscripten",
         target_os = "wasi",
         target_env = "sgx",
-        target_os = "xous"
+        target_os = "xous",
+        target_os = "trusty",
     ))
 ))]
 mod tests;
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index f64f034cce7..fd962b0415c 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -811,13 +811,17 @@ fn read_to_end_error() {
 }
 
 #[test]
-// Miri does not support signalling OOM
-#[cfg_attr(miri, ignore)]
-// 64-bit only to be sure the allocator will fail fast on an impossible to satisfy size
-#[cfg(target_pointer_width = "64")]
 fn try_oom_error() {
-    let mut v = Vec::<u8>::new();
-    let reserve_err = v.try_reserve(isize::MAX as usize - 1).unwrap_err();
+    use alloc::alloc::Layout;
+    use alloc::collections::{TryReserveError, TryReserveErrorKind};
+
+    // We simulate a `Vec::try_reserve` error rather than attempting a huge size for real. This way
+    // we're not subject to the whims of optimization that might skip the actual allocation, and it
+    // also works for 32-bit targets and miri that might not OOM at all.
+    let layout = Layout::new::<u8>();
+    let kind = TryReserveErrorKind::AllocError { layout, non_exhaustive: () };
+    let reserve_err = TryReserveError::from(kind);
+
     let io_err = io::Error::from(reserve_err);
     assert_eq!(io::ErrorKind::OutOfMemory, io_err.kind());
 }
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 5ac3dbc3e98..c07c391892d 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1064,7 +1064,7 @@ mod move_keyword {}
 /// ```rust,compile_fail,E0502
 /// let mut v = vec![0, 1];
 /// let mut_ref_v = &mut v;
-/// ##[allow(unused)]
+/// # #[allow(unused)]
 /// let ref_v = &v;
 /// mut_ref_v.push(2);
 /// ```
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index 9b68f872955..6a951426407 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -5,7 +5,8 @@
     not(any(
         target_os = "emscripten",
         all(target_os = "wasi", target_env = "p1"),
-        target_os = "xous"
+        target_os = "xous",
+        target_os = "trusty",
     ))
 ))]
 mod tests;
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index 3eb798ad34a..a97b3299774 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -4,7 +4,8 @@
         target_os = "emscripten",
         all(target_os = "wasi", target_env = "p1"),
         target_env = "sgx",
-        target_os = "xous"
+        target_os = "xous",
+        target_os = "trusty",
     ))
 ))]
 mod tests;
diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs
index 35de4860fe2..95cf4932e6e 100644
--- a/library/std/src/os/fd/mod.rs
+++ b/library/std/src/os/fd/mod.rs
@@ -13,6 +13,7 @@ mod raw;
 mod owned;
 
 // Implementations for `AsRawFd` etc. for network types.
+#[cfg(not(target_os = "trusty"))]
 mod net;
 
 #[cfg(test)]
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 5cec11ecccf..701cf823357 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -4,12 +4,20 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
 use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+#[cfg(not(target_os = "trusty"))]
+use crate::fs;
 use crate::marker::PhantomData;
 use crate::mem::ManuallyDrop;
-#[cfg(not(any(target_arch = "wasm32", target_env = "sgx", target_os = "hermit")))]
+#[cfg(not(any(
+    target_arch = "wasm32",
+    target_env = "sgx",
+    target_os = "hermit",
+    target_os = "trusty"
+)))]
 use crate::sys::cvt;
+#[cfg(not(target_os = "trusty"))]
 use crate::sys_common::{AsInner, FromInner, IntoInner};
-use crate::{fmt, fs, io};
+use crate::{fmt, io};
 
 type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>;
 
@@ -87,7 +95,7 @@ impl OwnedFd {
 impl BorrowedFd<'_> {
     /// Creates a new `OwnedFd` instance that shares the same underlying file
     /// description as the existing `BorrowedFd` instance.
-    #[cfg(not(any(target_arch = "wasm32", target_os = "hermit")))]
+    #[cfg(not(any(target_arch = "wasm32", target_os = "hermit", target_os = "trusty")))]
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
         // We want to atomically duplicate this file descriptor and set the
@@ -110,7 +118,7 @@ impl BorrowedFd<'_> {
 
     /// Creates a new `OwnedFd` instance that shares the same underlying file
     /// description as the existing `BorrowedFd` instance.
-    #[cfg(any(target_arch = "wasm32", target_os = "hermit"))]
+    #[cfg(any(target_arch = "wasm32", target_os = "hermit", target_os = "trusty"))]
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
         Err(crate::io::Error::UNSUPPORTED_PLATFORM)
@@ -280,6 +288,7 @@ impl AsFd for OwnedFd {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl AsFd for fs::File {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -288,6 +297,7 @@ impl AsFd for fs::File {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<fs::File> for OwnedFd {
     /// Takes ownership of a [`File`](fs::File)'s underlying file descriptor.
     #[inline]
@@ -297,6 +307,7 @@ impl From<fs::File> for OwnedFd {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<OwnedFd> for fs::File {
     /// Returns a [`File`](fs::File) that takes ownership of the given
     /// file descriptor.
@@ -307,6 +318,7 @@ impl From<OwnedFd> for fs::File {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl AsFd for crate::net::TcpStream {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -315,6 +327,7 @@ impl AsFd for crate::net::TcpStream {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<crate::net::TcpStream> for OwnedFd {
     /// Takes ownership of a [`TcpStream`](crate::net::TcpStream)'s socket file descriptor.
     #[inline]
@@ -324,6 +337,7 @@ impl From<crate::net::TcpStream> for OwnedFd {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<OwnedFd> for crate::net::TcpStream {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
@@ -334,6 +348,7 @@ impl From<OwnedFd> for crate::net::TcpStream {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl AsFd for crate::net::TcpListener {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -342,6 +357,7 @@ impl AsFd for crate::net::TcpListener {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<crate::net::TcpListener> for OwnedFd {
     /// Takes ownership of a [`TcpListener`](crate::net::TcpListener)'s socket file descriptor.
     #[inline]
@@ -351,6 +367,7 @@ impl From<crate::net::TcpListener> for OwnedFd {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<OwnedFd> for crate::net::TcpListener {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
@@ -361,6 +378,7 @@ impl From<OwnedFd> for crate::net::TcpListener {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl AsFd for crate::net::UdpSocket {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
@@ -369,6 +387,7 @@ impl AsFd for crate::net::UdpSocket {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<crate::net::UdpSocket> for OwnedFd {
     /// Takes ownership of a [`UdpSocket`](crate::net::UdpSocket)'s file descriptor.
     #[inline]
@@ -378,6 +397,7 @@ impl From<crate::net::UdpSocket> for OwnedFd {
 }
 
 #[stable(feature = "io_safety", since = "1.63.0")]
+#[cfg(not(target_os = "trusty"))]
 impl From<OwnedFd> for crate::net::UdpSocket {
     #[inline]
     fn from(owned_fd: OwnedFd) -> Self {
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 03dff94350d..083ac6e3fe6 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -5,6 +5,9 @@
 #[cfg(target_os = "hermit")]
 use hermit_abi as libc;
 
+#[cfg(not(target_os = "trusty"))]
+use crate::fs;
+use crate::io;
 #[cfg(target_os = "hermit")]
 use crate::os::hermit::io::OwnedFd;
 #[cfg(not(target_os = "hermit"))]
@@ -15,8 +18,8 @@ use crate::os::unix::io::AsFd;
 use crate::os::unix::io::OwnedFd;
 #[cfg(target_os = "wasi")]
 use crate::os::wasi::io::OwnedFd;
+#[cfg(not(target_os = "trusty"))]
 use crate::sys_common::{AsInner, IntoInner};
-use crate::{fs, io};
 
 /// Raw file descriptors.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -161,6 +164,7 @@ impl FromRawFd for RawFd {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(target_os = "trusty"))]
 impl AsRawFd for fs::File {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
@@ -168,6 +172,7 @@ impl AsRawFd for fs::File {
     }
 }
 #[stable(feature = "from_raw_os", since = "1.1.0")]
+#[cfg(not(target_os = "trusty"))]
 impl FromRawFd for fs::File {
     #[inline]
     unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
@@ -175,6 +180,7 @@ impl FromRawFd for fs::File {
     }
 }
 #[stable(feature = "into_raw_os", since = "1.4.0")]
+#[cfg(not(target_os = "trusty"))]
 impl IntoRawFd for fs::File {
     #[inline]
     fn into_raw_fd(self) -> RawFd {
@@ -183,6 +189,7 @@ impl IntoRawFd for fs::File {
 }
 
 #[stable(feature = "asraw_stdio", since = "1.21.0")]
+#[cfg(not(target_os = "trusty"))]
 impl AsRawFd for io::Stdin {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
@@ -207,6 +214,7 @@ impl AsRawFd for io::Stderr {
 }
 
 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
+#[cfg(not(target_os = "trusty"))]
 impl<'a> AsRawFd for io::StdinLock<'a> {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index e28a1c3e6d5..58cbecd30e5 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -169,6 +169,8 @@ pub mod rtems;
 pub mod solaris;
 #[cfg(target_os = "solid_asp3")]
 pub mod solid;
+#[cfg(target_os = "trusty")]
+pub mod trusty;
 #[cfg(target_os = "uefi")]
 pub mod uefi;
 #[cfg(target_os = "vita")]
@@ -178,7 +180,7 @@ pub mod vxworks;
 #[cfg(target_os = "xous")]
 pub mod xous;
 
-#[cfg(any(unix, target_os = "hermit", target_os = "wasi", doc))]
+#[cfg(any(unix, target_os = "hermit", target_os = "trusty", target_os = "wasi", doc))]
 pub mod fd;
 
 #[cfg(any(target_os = "linux", target_os = "android", doc))]
diff --git a/library/std/src/os/trusty/io/mod.rs b/library/std/src/os/trusty/io/mod.rs
new file mode 100644
index 00000000000..4cfd448305b
--- /dev/null
+++ b/library/std/src/os/trusty/io/mod.rs
@@ -0,0 +1,4 @@
+#![stable(feature = "os_fd", since = "1.66.0")]
+
+#[stable(feature = "os_fd", since = "1.66.0")]
+pub use crate::os::fd::*;
diff --git a/library/std/src/os/trusty/mod.rs b/library/std/src/os/trusty/mod.rs
new file mode 100644
index 00000000000..cc67c92d7ff
--- /dev/null
+++ b/library/std/src/os/trusty/mod.rs
@@ -0,0 +1,3 @@
+#![stable(feature = "rust1", since = "1.0.0")]
+
+pub mod io;
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index fa65a7c51bf..a084f452e55 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -531,7 +531,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> {
     ///     pub Y: i16,
     /// }
     ///
-    /// extern "system" {
+    /// unsafe extern "system" {
     ///     fn CreatePipe(
     ///         hreadpipe: *mut HANDLE,
     ///         hwritepipe: *mut HANDLE,
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index bdd4844b651..37762c65f65 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -154,7 +154,8 @@
         target_os = "emscripten",
         target_os = "wasi",
         target_env = "sgx",
-        target_os = "xous"
+        target_os = "xous",
+        target_os = "trusty",
     ))
 ))]
 mod tests;
diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs
index 2c0b533a570..8489e17c971 100644
--- a/library/std/src/sys/alloc/mod.rs
+++ b/library/std/src/sys/alloc/mod.rs
@@ -72,6 +72,7 @@ cfg_if::cfg_if! {
         target_family = "unix",
         target_os = "wasi",
         target_os = "teeos",
+        target_os = "trusty",
     ))] {
         mod unix;
     } else if #[cfg(target_os = "windows")] {
diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs
index 9be018c8a53..fbefc62ac88 100644
--- a/library/std/src/sys/pal/mod.rs
+++ b/library/std/src/sys/pal/mod.rs
@@ -37,6 +37,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "hermit")] {
         mod hermit;
         pub use self::hermit::*;
+    } else if #[cfg(target_os = "trusty")] {
+        mod trusty;
+        pub use self::trusty::*;
     } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] {
         mod wasip2;
         pub use self::wasip2::*;
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
index 301e3299c05..3fe6dee3d6f 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range};
 use crate::arch::asm;
 use crate::cell::UnsafeCell;
 use crate::convert::TryInto;
-use crate::mem::{self, ManuallyDrop};
+use crate::mem::{self, ManuallyDrop, MaybeUninit};
 use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut};
 use crate::pin::PinCoerceUnsized;
 use crate::ptr::{self, NonNull};
@@ -209,6 +209,45 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
     }
 }
 
+/// A type which can a destination for safely copying from userspace.
+///
+/// # Safety
+///
+/// Requires that `T` and `Self` have identical layouts.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub unsafe trait UserSafeCopyDestination<T: ?Sized> {
+    /// Returns a pointer for writing to the value.
+    fn as_mut_ptr(&mut self) -> *mut T;
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<T> for T {
+    fn as_mut_ptr(&mut self) -> *mut T {
+        self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<[T]> for [T] {
+    fn as_mut_ptr(&mut self) -> *mut [T] {
+        self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<T> for MaybeUninit<T> {
+    fn as_mut_ptr(&mut self) -> *mut T {
+        self as *mut Self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<[T]> for [MaybeUninit<T>] {
+    fn as_mut_ptr(&mut self) -> *mut [T] {
+        self as *mut Self as _
+    }
+}
+
 #[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: ?Sized> User<T>
 where
@@ -544,12 +583,12 @@ where
     /// # Panics
     /// This function panics if the destination doesn't have the same size as
     /// the source. This can happen for dynamically-sized types such as slices.
-    pub fn copy_to_enclave(&self, dest: &mut T) {
+    pub fn copy_to_enclave<U: ?Sized + UserSafeCopyDestination<T>>(&self, dest: &mut U) {
         unsafe {
             assert_eq!(size_of_val(dest), size_of_val(&*self.0.get()));
             copy_from_userspace(
                 self.0.get() as *const T as *const u8,
-                dest as *mut T as *mut u8,
+                dest.as_mut_ptr() as *mut u8,
                 size_of_val(dest),
             );
         }
@@ -639,25 +678,18 @@ where
         unsafe { (*self.0.get()).len() }
     }
 
-    /// Copies the value from user memory and place it into `dest`. Afterwards,
-    /// `dest` will contain exactly `self.len()` elements.
-    ///
-    /// # Panics
-    /// This function panics if the destination doesn't have the same size as
-    /// the source. This can happen for dynamically-sized types such as slices.
-    pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) {
-        if let Some(missing) = self.len().checked_sub(dest.capacity()) {
-            dest.reserve(missing)
-        }
+    /// Copies the value from user memory and appends it to `dest`.
+    pub fn append_to_enclave_vec(&self, dest: &mut Vec<T>) {
+        dest.reserve(self.len());
+        self.copy_to_enclave(&mut dest.spare_capacity_mut()[..self.len()]);
         // SAFETY: We reserve enough space above.
-        unsafe { dest.set_len(self.len()) };
-        self.copy_to_enclave(&mut dest[..]);
+        unsafe { dest.set_len(dest.len() + self.len()) };
     }
 
     /// Copies the value from user memory into a vector in enclave memory.
     pub fn to_enclave(&self) -> Vec<T> {
         let mut ret = Vec::with_capacity(self.len());
-        self.copy_to_enclave_vec(&mut ret);
+        self.append_to_enclave_vec(&mut ret);
         ret
     }
 
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
index 90b9b59471a..cbdaf439b28 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
@@ -1,5 +1,7 @@
 use crate::cmp;
-use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult};
+use crate::io::{
+    BorrowedCursor, Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult,
+};
 use crate::random::{DefaultRandomSource, Random};
 use crate::time::{Duration, Instant};
 
@@ -36,6 +38,19 @@ pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
     }
 }
 
+/// Usercall `read` with an uninitialized buffer. See the ABI documentation for
+/// more information.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> {
+    unsafe {
+        let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity());
+        let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?;
+        userbuf[..len].copy_to_enclave(&mut buf.as_mut()[..len]);
+        buf.advance_unchecked(len);
+        Ok(())
+    }
+}
+
 /// Usercall `read_alloc`. See the ABI documentation for more information.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
diff --git a/library/std/src/sys/pal/sgx/fd.rs b/library/std/src/sys/pal/sgx/fd.rs
index 3bb3189a1d1..399f6a16489 100644
--- a/library/std/src/sys/pal/sgx/fd.rs
+++ b/library/std/src/sys/pal/sgx/fd.rs
@@ -29,7 +29,7 @@ impl FileDesc {
     }
 
     pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
-        crate::io::default_read_buf(|b| self.read(b), buf)
+        usercalls::read_buf(self.fd, buf)
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs
new file mode 100644
index 00000000000..7034b643d8e
--- /dev/null
+++ b/library/std/src/sys/pal/trusty/mod.rs
@@ -0,0 +1,21 @@
+//! System bindings for the Trusty OS.
+
+#[path = "../unsupported/args.rs"]
+pub mod args;
+#[path = "../unsupported/common.rs"]
+#[deny(unsafe_op_in_unsafe_fn)]
+mod common;
+#[path = "../unsupported/env.rs"]
+pub mod env;
+#[path = "../unsupported/os.rs"]
+pub mod os;
+#[path = "../unsupported/pipe.rs"]
+pub mod pipe;
+#[path = "../unsupported/process.rs"]
+pub mod process;
+#[path = "../unsupported/thread.rs"]
+pub mod thread;
+#[path = "../unsupported/time.rs"]
+pub mod time;
+
+pub use common::*;
diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs
index f42351deb92..870039602bc 100644
--- a/library/std/src/sys/random/mod.rs
+++ b/library/std/src/sys/random/mod.rs
@@ -60,6 +60,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "teeos")] {
         mod teeos;
         pub use teeos::fill_bytes;
+    } else if #[cfg(target_os = "trusty")] {
+        mod trusty;
+        pub use trusty::fill_bytes;
     } else if #[cfg(target_os = "uefi")] {
         mod uefi;
         pub use uefi::fill_bytes;
diff --git a/library/std/src/sys/random/trusty.rs b/library/std/src/sys/random/trusty.rs
new file mode 100644
index 00000000000..da6ca3eea24
--- /dev/null
+++ b/library/std/src/sys/random/trusty.rs
@@ -0,0 +1,7 @@
+extern "C" {
+    fn trusty_rng_secure_rand(randomBuffer: *mut core::ffi::c_void, randomBufferLen: libc::size_t);
+}
+
+pub fn fill_bytes(bytes: &mut [u8]) {
+    unsafe { trusty_rng_secure_rand(bytes.as_mut_ptr().cast(), bytes.len()) }
+}
diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs
index 2a9167bfe96..336d4c8527d 100644
--- a/library/std/src/sys/stdio/mod.rs
+++ b/library/std/src/sys/stdio/mod.rs
@@ -19,6 +19,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "teeos")] {
         mod teeos;
         pub use teeos::*;
+    } else if #[cfg(target_os = "trusty")] {
+        mod trusty;
+        pub use trusty::*;
     } else if #[cfg(target_os = "uefi")] {
         mod uefi;
         pub use uefi::*;
diff --git a/library/std/src/sys/stdio/sgx.rs b/library/std/src/sys/stdio/sgx.rs
index 03d754cb217..1894c098d18 100644
--- a/library/std/src/sys/stdio/sgx.rs
+++ b/library/std/src/sys/stdio/sgx.rs
@@ -1,6 +1,6 @@
 use fortanix_sgx_abi as abi;
 
-use crate::io;
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::sys::fd::FileDesc;
 
 pub struct Stdin(());
@@ -24,6 +24,19 @@ impl io::Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         with_std_fd(abi::FD_STDIN, |fd| fd.read(buf))
     }
+
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        with_std_fd(abi::FD_STDIN, |fd| fd.read_buf(buf))
+    }
+
+    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDIN, |fd| fd.read_vectored(bufs))
+    }
+
+    #[inline]
+    fn is_read_vectored(&self) -> bool {
+        true
+    }
 }
 
 impl Stdout {
@@ -40,6 +53,15 @@ impl io::Write for Stdout {
     fn flush(&mut self) -> io::Result<()> {
         with_std_fd(abi::FD_STDOUT, |fd| fd.flush())
     }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDOUT, |fd| fd.write_vectored(bufs))
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
 }
 
 impl Stderr {
@@ -56,6 +78,15 @@ impl io::Write for Stderr {
     fn flush(&mut self) -> io::Result<()> {
         with_std_fd(abi::FD_STDERR, |fd| fd.flush())
     }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDERR, |fd| fd.write_vectored(bufs))
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
 }
 
 pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
diff --git a/library/std/src/sys/stdio/trusty.rs b/library/std/src/sys/stdio/trusty.rs
new file mode 100644
index 00000000000..d393e95394d
--- /dev/null
+++ b/library/std/src/sys/stdio/trusty.rs
@@ -0,0 +1,81 @@
+use crate::io;
+
+pub struct Stdin;
+pub struct Stdout;
+pub struct Stderr;
+
+impl Stdin {
+    pub const fn new() -> Stdin {
+        Stdin
+    }
+}
+
+impl io::Read for Stdin {
+    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+        Ok(0)
+    }
+}
+
+impl Stdout {
+    pub const fn new() -> Stdout {
+        Stdout
+    }
+}
+
+impl io::Write for Stdout {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        _write(libc::STDOUT_FILENO, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl Stderr {
+    pub const fn new() -> Stderr {
+        Stderr
+    }
+}
+
+impl io::Write for Stderr {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        _write(libc::STDERR_FILENO, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+pub const STDIN_BUF_SIZE: usize = 0;
+
+pub fn is_ebadf(_err: &io::Error) -> bool {
+    true
+}
+
+pub fn panic_output() -> Option<impl io::Write> {
+    Some(Stderr)
+}
+
+fn _write(fd: i32, message: &[u8]) -> io::Result<usize> {
+    let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() };
+    loop {
+        // SAFETY: syscall, safe arguments.
+        let ret = unsafe { libc::writev(fd, &iov, 1) };
+        if ret < 0 {
+            return Err(io::Error::last_os_error());
+        }
+        let ret = ret as usize;
+        if ret > iov.iov_len {
+            return Err(io::Error::last_os_error());
+        }
+        if ret == iov.iov_len {
+            return Ok(message.len());
+        }
+        // SAFETY: ret has been checked to be less than the length of
+        // the buffer
+        iov.iov_base = unsafe { iov.iov_base.add(ret) };
+        iov.iov_len -= ret;
+    }
+}
diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index f0a13323ec9..1ff13154b7b 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -28,6 +28,7 @@ cfg_if::cfg_if! {
         all(target_family = "wasm", not(target_feature = "atomics")),
         target_os = "uefi",
         target_os = "zkvm",
+        target_os = "trusty",
     ))] {
         mod statik;
         pub use statik::{EagerStorage, LazyStorage, thread_local_inner};
@@ -91,6 +92,7 @@ pub(crate) mod guard {
             )),
             target_os = "uefi",
             target_os = "zkvm",
+            target_os = "trusty",
         ))] {
             pub(crate) fn enable() {
                 // FIXME: Right now there is no concept of "thread exit" on
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
index 0f6fa2d291a..ec6ae31507e 100644
--- a/library/sysroot/Cargo.toml
+++ b/library/sysroot/Cargo.toml
@@ -3,7 +3,7 @@ cargo-features = ["public-dependency"]
 [package]
 name = "sysroot"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 
 # this is a dummy crate to ensure that all required crates appear in the sysroot
 [dependencies]
diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml
index 241ef324b00..2a32a7dd76e 100644
--- a/library/test/Cargo.toml
+++ b/library/test/Cargo.toml
@@ -3,7 +3,7 @@ cargo-features = ["public-dependency"]
 [package]
 name = "test"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml
index 66e8d1a3ffe..da60924c2b4 100644
--- a/library/unwind/Cargo.toml
+++ b/library/unwind/Cargo.toml
@@ -3,7 +3,7 @@ name = "unwind"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
-edition = "2021"
+edition = "2024"
 include = [
   '/libunwind/*',
 ]
diff --git a/library/windows_targets/Cargo.toml b/library/windows_targets/Cargo.toml
index 94d7c821064..705c9e04381 100644
--- a/library/windows_targets/Cargo.toml
+++ b/library/windows_targets/Cargo.toml
@@ -2,7 +2,7 @@
 name = "windows-targets"
 description = "A drop-in replacement for the real windows-targets crate for use in std only."
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 
 [features]
 # Enable using raw-dylib for Windows imports.
diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index 939fab7d5fe..c7d158584eb 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -12,7 +12,7 @@ pub macro link {
     ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
         #[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))]
         #[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))]
-        extern $abi {
+        unsafe extern $abi {
             $(#[link_name=$link_name])?
             pub fn $($function)*;
         }
@@ -26,7 +26,7 @@ pub macro link {
         // libraries below by using an empty extern block. This works because extern blocks are not
         // connected to the library given in the #[link] attribute.
         #[link(name = "kernel32")]
-        extern $abi {
+        unsafe extern $abi {
             $(#[link_name=$link_name])?
             pub fn $($function)*;
         }
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index 18aa3119842..e67bc62a603 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -454,7 +454,6 @@ tool_check_step!(Rustdoc { path: "src/tools/rustdoc", alt_path: "src/librustdoc"
 tool_check_step!(Clippy { path: "src/tools/clippy" });
 tool_check_step!(Miri { path: "src/tools/miri" });
 tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri" });
-tool_check_step!(Rls { path: "src/tools/rls" });
 tool_check_step!(Rustfmt { path: "src/tools/rustfmt" });
 tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" });
 tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" });
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index fe8c89f7a53..d3ab215d1b5 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -346,7 +346,6 @@ lint_any!(
     OptDist, "src/tools/opt-dist", "opt-dist";
     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client";
     RemoteTestServer, "src/tools/remote-test-server", "remote-test-server";
-    Rls, "src/tools/rls", "rls";
     RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer";
     Rustdoc, "src/librustdoc", "clippy";
     Rustfmt, "src/tools/rustfmt", "rustfmt";
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index ec0edeab996..c393eb55c62 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1158,48 +1158,6 @@ impl Step for Cargo {
 }
 
 #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
-pub struct Rls {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
-}
-
-impl Step for Rls {
-    type Output = Option<GeneratedTarball>;
-    const ONLY_HOSTS: bool = true;
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        let default = should_build_extended_tool(run.builder, "rls");
-        run.alias("rls").default_condition(default)
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Rls {
-            compiler: run.builder.compiler_for(
-                run.builder.top_stage,
-                run.builder.config.build,
-                run.target,
-            ),
-            target: run.target,
-        });
-    }
-
-    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
-        let compiler = self.compiler;
-        let target = self.target;
-
-        let rls = builder.ensure(tool::Rls { compiler, target });
-
-        let mut tarball = Tarball::new(builder, "rls", &target.triple);
-        tarball.set_overlay(OverlayKind::Rls);
-        tarball.is_preview(true);
-        tarball.add_file(rls.tool_path, "bin", 0o755);
-        tarball.add_legal_and_readme_to("share/doc/rls");
-        Some(tarball.generate())
-    }
-}
-
-#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
 pub struct RustAnalyzer {
     pub compiler: Compiler,
     pub target: TargetSelection,
@@ -1528,7 +1486,6 @@ impl Step for Extended {
         add_component!("rust-json-docs" => JsonDocs { host: target });
         add_component!("cargo" => Cargo { compiler, target });
         add_component!("rustfmt" => Rustfmt { compiler, target });
-        add_component!("rls" => Rls { compiler, target });
         add_component!("rust-analyzer" => RustAnalyzer { compiler, target });
         add_component!("llvm-components" => LlvmTools { target });
         add_component!("clippy" => Clippy { compiler, target });
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index f25dfaab0f1..e198a8dd6a5 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -85,9 +85,7 @@ impl FromStr for Profile {
             "lib" | "library" => Ok(Profile::Library),
             "compiler" => Ok(Profile::Compiler),
             "maintainer" | "dist" | "user" => Ok(Profile::Dist),
-            "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => {
-                Ok(Profile::Tools)
-            }
+            "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" => Ok(Profile::Tools),
             "none" => Ok(Profile::None),
             "llvm" | "codegen" => Err("the \"llvm\" and \"codegen\" profiles have been removed,\
                 use \"compiler\" instead which has the same functionality"
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index e0cf2c12139..016f09cb2a8 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -228,7 +228,6 @@ pub fn prepare_tool_cargo(
     let mut features = extra_features.to_vec();
     if builder.build.config.cargo_native_static {
         if path.ends_with("cargo")
-            || path.ends_with("rls")
             || path.ends_with("clippy")
             || path.ends_with("miri")
             || path.ends_with("rustfmt")
@@ -1231,7 +1230,6 @@ tool_extended!(CargoMiri {
     stable: false,
     add_bins_to_sysroot: ["cargo-miri"]
 });
-tool_extended!(Rls { path: "src/tools/rls", tool_name: "rls", stable: true });
 tool_extended!(Rustfmt {
     path: "src/tools/rustfmt",
     tool_name: "rustfmt",
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 8e1cecfcd18..0b49751f73c 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -895,7 +895,6 @@ impl<'a> Builder<'a> {
                 tool::RemoteTestClient,
                 tool::RustInstaller,
                 tool::Cargo,
-                tool::Rls,
                 tool::RustAnalyzer,
                 tool::RustAnalyzerProcMacroSrv,
                 tool::Rustdoc,
@@ -938,7 +937,6 @@ impl<'a> Builder<'a> {
                 clippy::OptDist,
                 clippy::RemoteTestClient,
                 clippy::RemoteTestServer,
-                clippy::Rls,
                 clippy::RustAnalyzer,
                 clippy::Rustdoc,
                 clippy::Rustfmt,
@@ -956,7 +954,6 @@ impl<'a> Builder<'a> {
                 check::Miri,
                 check::CargoMiri,
                 check::MiroptTestTools,
-                check::Rls,
                 check::Rustfmt,
                 check::RustAnalyzer,
                 check::TestFloatParse,
@@ -1071,7 +1068,6 @@ impl<'a> Builder<'a> {
                 dist::Analysis,
                 dist::Src,
                 dist::Cargo,
-                dist::Rls,
                 dist::RustAnalyzer,
                 dist::Rustfmt,
                 dist::Clippy,
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 994ccabf0eb..fc408437838 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -253,7 +253,7 @@ pub enum Mode {
     /// Build a tool which uses the locally built rustc and the target std,
     /// placing the output in the "stageN-tools" directory. This is used for
     /// anything that needs a fully functional rustc, such as rustdoc, clippy,
-    /// cargo, rls, rustfmt, miri, etc.
+    /// cargo, rustfmt, miri, etc.
     ToolRustc,
 }
 
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index ec27109c117..8036c592108 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -375,4 +375,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "There is now a new `gcc` config section that can be used to download GCC from CI using `gcc.download-ci-gcc = true`",
     },
+    ChangeInfo {
+        change_id: 126856,
+        severity: ChangeSeverity::Warning,
+        summary: "Removed `src/tools/rls` tool as it was deprecated long time ago.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs
index 843ea65e838..f1678bacc97 100644
--- a/src/bootstrap/src/utils/tarball.rs
+++ b/src/bootstrap/src/utils/tarball.rs
@@ -22,7 +22,6 @@ pub(crate) enum OverlayKind {
     Clippy,
     Miri,
     Rustfmt,
-    Rls,
     RustAnalyzer,
     RustcCodegenCranelift,
     LlvmBitcodeLinker,
@@ -56,7 +55,6 @@ impl OverlayKind {
                 "src/tools/rustfmt/LICENSE-APACHE",
                 "src/tools/rustfmt/LICENSE-MIT",
             ],
-            OverlayKind::Rls => &["src/tools/rls/README.md", "LICENSE-APACHE", "LICENSE-MIT"],
             OverlayKind::RustAnalyzer => &[
                 "src/tools/rust-analyzer/README.md",
                 "src/tools/rust-analyzer/LICENSE-APACHE",
@@ -90,7 +88,6 @@ impl OverlayKind {
             OverlayKind::Rustfmt => {
                 builder.rustfmt_info.version(builder, &builder.release_num("rustfmt"))
             }
-            OverlayKind::Rls => builder.release(&builder.release_num("rls")),
             OverlayKind::RustAnalyzer => builder
                 .rust_analyzer_info
                 .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")),
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 70880e0d61f..c74a9e98496 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -265,7 +265,7 @@ target | std | host | notes
 [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
 [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ |  | ARM64 Redox OS
 [`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? |  | ARM64 TEEOS |
-[`aarch64-unknown-trusty`](platform-support/trusty.md) | ? |  |
+[`aarch64-unknown-trusty`](platform-support/trusty.md) | ✓ |  |
 [`aarch64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ |  |
 [`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  | ARM64 VxWorks OS
 `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
@@ -290,7 +290,7 @@ target | std | host | notes
 [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat
 [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
 [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
-[`armv7-unknown-trusty`](platform-support/trusty.md) | ? |  |
+[`armv7-unknown-trusty`](platform-support/trusty.md) | ✓ |  |
 [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ |  | Armv7-A for VxWorks
 [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3
 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3, hardfloat
@@ -419,7 +419,7 @@ target | std | host | notes
 `x86_64-unknown-l4re-uclibc` | ? |  |
 [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * |  | 64-bit Linux with no libc
 [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD
-[`x86_64-unknown-trusty`](platform-support/trusty.md) | ? |  |
+[`x86_64-unknown-trusty`](platform-support/trusty.md) | ✓ |  |
 `x86_64-uwp-windows-gnu` | ✓ |  |
 [`x86_64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ |  |
 [`x86_64-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ |   | 64-bit Windows 7 support
diff --git a/src/doc/rustc/src/platform-support/trusty.md b/src/doc/rustc/src/platform-support/trusty.md
index 6b37543b600..73fcbbdddca 100644
--- a/src/doc/rustc/src/platform-support/trusty.md
+++ b/src/doc/rustc/src/platform-support/trusty.md
@@ -16,8 +16,10 @@ Environment (TEE) for Android.
 
 These targets are cross-compiled. They have no special requirements for the host.
 
-Support for the standard library is work-in-progress. It is expected that
-they will support alloc with the default allocator, and partially support std.
+Trusty targets have partial support for the standard library: `alloc` is fully
+supported and `std` has limited support that excludes things like filesystem
+access, network I/O, and spawning processes/threads. File descriptors are
+supported for the purpose of IPC.
 
 Trusty uses the ELF file format.
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 9606ba76991..26a3c0ada35 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -7,14 +7,13 @@
 use rustc_abi::ExternAbi;
 use rustc_ast::ast;
 use rustc_attr_parsing::DeprecatedSince;
-use rustc_hir::def::{CtorKind, DefKind};
+use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
 use rustc_metadata::rendered_const;
 use rustc_middle::{bug, ty};
-use rustc_span::{Pos, Symbol, sym};
+use rustc_span::{Pos, Symbol};
 use rustdoc_json_types::*;
 
-use super::FullItemId;
 use crate::clean::{self, ItemId};
 use crate::formats::FormatRenderer;
 use crate::formats::item_type::ItemType;
@@ -108,67 +107,6 @@ impl JsonRenderer<'_> {
         }
     }
 
-    pub(crate) fn id_from_item_default(&self, item_id: ItemId) -> Id {
-        self.id_from_item_inner(item_id, None, None)
-    }
-
-    pub(crate) fn id_from_item_inner(
-        &self,
-        item_id: ItemId,
-        name: Option<Symbol>,
-        extra: Option<Id>,
-    ) -> Id {
-        let make_part = |def_id: DefId, name: Option<Symbol>, extra: Option<Id>| {
-            let name = match name {
-                Some(name) => Some(name),
-                None => {
-                    // We need this workaround because primitive types' DefId actually refers to
-                    // their parent module, which isn't present in the output JSON items. So
-                    // instead, we directly get the primitive symbol
-                    if matches!(self.tcx.def_kind(def_id), DefKind::Mod)
-                        && let Some(prim) = self
-                            .tcx
-                            .get_attrs(def_id, sym::rustc_doc_primitive)
-                            .find_map(|attr| attr.value_str())
-                    {
-                        Some(prim)
-                    } else {
-                        self.tcx.opt_item_name(def_id)
-                    }
-                }
-            };
-
-            FullItemId { def_id, name, extra }
-        };
-
-        let key = match item_id {
-            ItemId::DefId(did) => (make_part(did, name, extra), None),
-            ItemId::Blanket { for_, impl_id } => {
-                (make_part(impl_id, None, None), Some(make_part(for_, name, extra)))
-            }
-            ItemId::Auto { for_, trait_ } => {
-                (make_part(trait_, None, None), Some(make_part(for_, name, extra)))
-            }
-        };
-
-        let mut interner = self.id_interner.borrow_mut();
-        let len = interner.len();
-        *interner
-            .entry(key)
-            .or_insert_with(|| Id(len.try_into().expect("too many items in a crate")))
-    }
-
-    pub(crate) fn id_from_item(&self, item: &clean::Item) -> Id {
-        match item.kind {
-            clean::ItemKind::ImportItem(ref import) => {
-                let extra =
-                    import.source.did.map(ItemId::from).map(|i| self.id_from_item_default(i));
-                self.id_from_item_inner(item.item_id, item.name, extra)
-            }
-            _ => self.id_from_item_inner(item.item_id, item.name, None),
-        }
-    }
-
     fn ids(&self, items: impl IntoIterator<Item = clean::Item>) -> Vec<Id> {
         items
             .into_iter()
diff --git a/src/librustdoc/json/ids.rs b/src/librustdoc/json/ids.rs
new file mode 100644
index 00000000000..737148bad4e
--- /dev/null
+++ b/src/librustdoc/json/ids.rs
@@ -0,0 +1,122 @@
+//! Id handling for rustdoc-json.
+//!
+//! Manages the creation of [`rustdoc_json_types::Id`] and the
+//! fact that these don't correspond exactly to [`DefId`], because
+//! [`rustdoc_json_types::Item`] doesn't correspond exactly to what
+//! other phases think of as an "item".
+
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::DefId;
+use rustc_span::{Symbol, sym};
+use rustdoc_json_types as types;
+
+use super::JsonRenderer;
+use crate::clean;
+
+pub(super) type IdInterner = FxHashMap<FullItemId, types::Id>;
+
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
+/// An uninterned id.
+///
+/// Each one corresponds to exactly one of both:
+/// 1. [`rustdoc_json_types::Item`].
+/// 2. [`rustdoc_json_types::Id`] transitively (as each `Item` has an `Id`).
+///
+/// It's *broadly* equivalent to a [`DefId`], but needs slightly more information
+/// to fully disambiguate items, because sometimes we choose to split a single HIR
+/// item into multiple JSON items, or have items with no corresponding HIR item.
+pub(super) struct FullItemId {
+    /// The "main" id of the item.
+    ///
+    /// In most cases this uniquely identifies the item, the other fields are just
+    /// used for edge-cases.
+    def_id: DefId,
+
+    /// An extra [`DefId`], which we need for:
+    ///
+    /// 1. Auto-trait impls synthesized by rustdoc.
+    /// 2. Blanket impls synthesized by rustdoc.
+    /// 3. Splitting of reexports of multiple items.
+    ///
+    ///    E.g:
+    ///
+    ///    ```rust
+    ///    mod module {
+    ///        pub struct Foo {} // Exists in type namespace
+    ///        pub fn Foo(){} // Exists in value namespace
+    ///    }
+    ///
+    ///    pub use module::Foo; // Imports both items
+    ///    ```
+    ///
+    ///    In HIR, the `pub use` is just 1 item, but in rustdoc-json it's 2, so
+    ///    we need to disambiguate.
+    extra_id: Option<DefId>,
+
+    /// Needed for `#[rustc_doc_primitive]` modules.
+    ///
+    /// For these, 1 [`DefId`] is used for both the primitive and the fake-module
+    /// that holds its docs.
+    ///
+    /// N.B. This only matters when documenting the standard library with
+    /// `--document-private-items`. Maybe we should delete that module, and
+    /// remove this.
+    name: Option<Symbol>,
+}
+
+impl JsonRenderer<'_> {
+    pub(crate) fn id_from_item_default(&self, item_id: clean::ItemId) -> types::Id {
+        self.id_from_item_inner(item_id, None, None)
+    }
+
+    fn id_from_item_inner(
+        &self,
+        item_id: clean::ItemId,
+        name: Option<Symbol>,
+        imported_id: Option<DefId>,
+    ) -> types::Id {
+        let (def_id, extra_id) = match item_id {
+            clean::ItemId::DefId(did) => (did, imported_id),
+            clean::ItemId::Blanket { for_, impl_id } => (for_, Some(impl_id)),
+            clean::ItemId::Auto { for_, trait_ } => (for_, Some(trait_)),
+        };
+
+        let name = match name {
+            Some(name) => Some(name),
+            None => {
+                // We need this workaround because primitive types' DefId actually refers to
+                // their parent module, which isn't present in the output JSON items. So
+                // instead, we directly get the primitive symbol
+                if matches!(self.tcx.def_kind(def_id), DefKind::Mod)
+                    && let Some(prim) = self
+                        .tcx
+                        .get_attrs(def_id, sym::rustc_doc_primitive)
+                        .find_map(|attr| attr.value_str())
+                {
+                    Some(prim)
+                } else {
+                    self.tcx.opt_item_name(def_id)
+                }
+            }
+        };
+
+        let key = FullItemId { def_id, extra_id, name };
+
+        let mut interner = self.id_interner.borrow_mut();
+        let len = interner.len();
+        *interner
+            .entry(key)
+            .or_insert_with(|| types::Id(len.try_into().expect("too many items in a crate")))
+    }
+
+    pub(crate) fn id_from_item(&self, item: &clean::Item) -> types::Id {
+        match item.kind {
+            clean::ItemKind::ImportItem(ref import) => {
+                let imported_id = import.source.did;
+                self.id_from_item_inner(item.item_id, item.name, imported_id)
+            }
+            _ => self.id_from_item_inner(item.item_id, item.name, None),
+        }
+    }
+}
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 6f8cf25554f..ba27eed7c11 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -5,6 +5,7 @@
 //! docs for usage and details.
 
 mod conversions;
+mod ids;
 mod import_finder;
 
 use std::cell::RefCell;
@@ -16,7 +17,6 @@ use std::rc::Rc;
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
-use rustc_span::Symbol;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustdoc_json_types as types;
 // It's important to use the FxHashMap from rustdoc_json_types here, instead of
@@ -35,14 +35,6 @@ use crate::formats::cache::Cache;
 use crate::json::conversions::IntoJson;
 use crate::{clean, try_err};
 
-#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
-struct FullItemId {
-    def_id: DefId,
-    name: Option<Symbol>,
-    /// Used to distinguish imports of different items with the same name
-    extra: Option<types::Id>,
-}
-
 #[derive(Clone)]
 pub(crate) struct JsonRenderer<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -55,7 +47,7 @@ pub(crate) struct JsonRenderer<'tcx> {
     out_dir: Option<PathBuf>,
     cache: Rc<Cache>,
     imported_items: DefIdSet,
-    id_interner: Rc<RefCell<FxHashMap<(FullItemId, Option<FullItemId>), types::Id>>>,
+    id_interner: Rc<RefCell<ids::IdInterner>>,
 }
 
 impl<'tcx> JsonRenderer<'tcx> {
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index dfc8f3bc7e0..741d7e3fa16 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -386,7 +386,6 @@ impl Builder {
         // NOTE: this profile is effectively deprecated; do not add new components to it.
         let mut complete = default;
         complete.extend([
-            Rls,
             RustAnalyzer,
             RustSrc,
             LlvmTools,
@@ -475,7 +474,6 @@ impl Builder {
                 // but might be marked as unavailable if they weren't built.
                 PkgType::Clippy
                 | PkgType::Miri
-                | PkgType::Rls
                 | PkgType::RustAnalyzer
                 | PkgType::Rustfmt
                 | PkgType::LlvmTools
diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs
index 495cab582eb..6ef8a0e83de 100644
--- a/src/tools/build-manifest/src/versions.rs
+++ b/src/tools/build-manifest/src/versions.rs
@@ -51,7 +51,6 @@ pkg_type! {
     Cargo = "cargo",
     HtmlDocs = "rust-docs",
     RustAnalysis = "rust-analysis",
-    Rls = "rls"; preview = true,
     RustAnalyzer = "rust-analyzer"; preview = true,
     Clippy = "clippy"; preview = true,
     Rustfmt = "rustfmt"; preview = true,
@@ -77,7 +76,6 @@ impl PkgType {
     fn should_use_rust_version(&self) -> bool {
         match self {
             PkgType::Cargo => false,
-            PkgType::Rls => false,
             PkgType::RustAnalyzer => false,
             PkgType::Clippy => false,
             PkgType::Rustfmt => false,
@@ -118,7 +116,6 @@ impl PkgType {
             HtmlDocs => HOSTS,
             JsonDocs => HOSTS,
             RustSrc => &["*"],
-            Rls => HOSTS,
             RustAnalyzer => HOSTS,
             Clippy => HOSTS,
             Miri => HOSTS,
diff --git a/src/tools/rls/Cargo.toml b/src/tools/rls/Cargo.toml
deleted file mode 100644
index b7aa659c25a..00000000000
--- a/src/tools/rls/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "rls"
-version = "2.0.0"
-edition = "2021"
-license = "Apache-2.0/MIT"
-
-[dependencies]
-serde_json = "1.0.83"
diff --git a/src/tools/rls/README.md b/src/tools/rls/README.md
deleted file mode 100644
index 43c331c413f..00000000000
--- a/src/tools/rls/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# RLS Stub
-
-RLS has been replaced with [rust-analyzer](https://rust-analyzer.github.io/).
-
-This directory contains a stub which replaces RLS with a simple LSP server
-which only displays an alert to the user that RLS is no longer available.
diff --git a/src/tools/rls/src/main.rs b/src/tools/rls/src/main.rs
deleted file mode 100644
index 3a95b47cd4d..00000000000
--- a/src/tools/rls/src/main.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//! RLS stub.
-//!
-//! This is a small stub that replaces RLS to alert the user that RLS is no
-//! longer available.
-
-use std::error::Error;
-use std::io::{BufRead, Write};
-
-use serde_json::Value;
-
-const ALERT_MSG: &str = "\
-RLS is no longer available as of Rust 1.65.
-Consider migrating to rust-analyzer instead.
-See https://rust-analyzer.github.io/ for installation instructions.
-";
-
-fn main() {
-    if let Err(e) = run() {
-        eprintln!("error: {e}");
-        std::process::exit(1);
-    }
-}
-
-struct Message {
-    method: Option<String>,
-}
-
-fn run() -> Result<(), Box<dyn Error>> {
-    let mut stdin = std::io::stdin().lock();
-    let mut stdout = std::io::stdout().lock();
-
-    let init = read_message(&mut stdin)?;
-    if init.method.as_deref() != Some("initialize") {
-        return Err(format!("expected initialize, got {:?}", init.method).into());
-    }
-    // No response, the LSP specification says that `showMessageRequest` may
-    // be posted before during this phase.
-
-    // message_type 1 is "Error"
-    let alert = serde_json::json!({
-        "jsonrpc": "2.0",
-        "id": 1,
-        "method": "window/showMessageRequest",
-        "params": {
-            "message_type": "1",
-            "message": ALERT_MSG
-        }
-    });
-    write_message_raw(&mut stdout, serde_json::to_string(&alert).unwrap())?;
-
-    loop {
-        let message = read_message(&mut stdin)?;
-        if message.method.as_deref() == Some("shutdown") {
-            std::process::exit(0);
-        }
-    }
-}
-
-fn read_message_raw<R: BufRead>(reader: &mut R) -> Result<String, Box<dyn Error>> {
-    let mut content_length: usize = 0;
-
-    // Read headers.
-    loop {
-        let mut line = String::new();
-        reader.read_line(&mut line)?;
-        if line.is_empty() {
-            return Err("remote disconnected".into());
-        }
-        if line == "\r\n" {
-            break;
-        }
-        if line.to_lowercase().starts_with("content-length:") {
-            let value = &line[15..].trim();
-            content_length = usize::from_str_radix(value, 10)?;
-        }
-    }
-    if content_length == 0 {
-        return Err("no content-length".into());
-    }
-
-    let mut buffer = vec![0; content_length];
-    reader.read_exact(&mut buffer)?;
-    let content = String::from_utf8(buffer)?;
-
-    Ok(content)
-}
-
-fn read_message<R: BufRead>(reader: &mut R) -> Result<Message, Box<dyn Error>> {
-    let m = read_message_raw(reader)?;
-    match serde_json::from_str::<Value>(&m) {
-        Ok(message) => Ok(Message {
-            method: message.get("method").and_then(|value| value.as_str().map(String::from)),
-        }),
-        Err(e) => Err(format!("failed to parse message {m}\n{e}").into()),
-    }
-}
-
-fn write_message_raw<W: Write>(mut writer: W, output: String) -> Result<(), Box<dyn Error>> {
-    write!(writer, "Content-Length: {}\r\n\r\n{}", output.len(), output)?;
-    writer.flush()?;
-    Ok(())
-}
diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs
index edf7658d25f..08ee5c16c12 100644
--- a/src/tools/tidy/src/walk.rs
+++ b/src/tools/tidy/src/walk.rs
@@ -32,8 +32,6 @@ pub fn filter_dirs(path: &Path) -> bool {
         "src/doc/rustc-dev-guide",
         "src/doc/reference",
         "src/gcc",
-        // Filter RLS output directories
-        "target/rls",
         "src/bootstrap/target",
         "vendor",
     ];
diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs
index 6483e27c97a..3fe795178b7 100644
--- a/tests/codegen/naked-fn/naked-functions.rs
+++ b/tests/codegen/naked-fn/naked-functions.rs
@@ -1,10 +1,12 @@
 //@ add-core-stubs
-//@ revisions: linux win macos thumb
+//@ revisions: linux win_x86 win_i686 macos thumb
 //
 //@[linux] compile-flags: --target x86_64-unknown-linux-gnu
 //@[linux] needs-llvm-components: x86
-//@[win] compile-flags: --target x86_64-pc-windows-gnu
-//@[win] needs-llvm-components: x86
+//@[win_x86] compile-flags: --target x86_64-pc-windows-gnu
+//@[win_x86] needs-llvm-components: x86
+//@[win_i686] compile-flags: --target i686-pc-windows-gnu
+//@[win_i686] needs-llvm-components: x86
 //@[macos] compile-flags: --target aarch64-apple-darwin
 //@[macos] needs-llvm-components: arm
 //@[thumb] compile-flags: --target thumbv7em-none-eabi
@@ -19,10 +21,11 @@ use minicore::*;
 
 // linux,win: .intel_syntax
 //
-// linux:   .pushsection .text.naked_empty,\22ax\22, @progbits
-// macos:   .pushsection __TEXT,__text,regular,pure_instructions
-// win: .pushsection .text.naked_empty,\22xr\22
-// thumb:   .pushsection .text.naked_empty,\22ax\22, %progbits
+// linux:    .pushsection .text.naked_empty,\22ax\22, @progbits
+// macos:    .pushsection __TEXT,__text,regular,pure_instructions
+// win_x86:  .pushsection .text.naked_empty,\22xr\22
+// win_i686: .pushsection .text._naked_empty,\22xr\22
+// thumb:    .pushsection .text.naked_empty,\22ax\22, %progbits
 //
 // CHECK: .balign 4
 //
@@ -34,10 +37,12 @@ use minicore::*;
 //
 // linux: .type naked_empty, @function
 //
-// win: .def naked_empty
-// win: .scl 2
-// win: .type 32
-// win: .endef naked_empty
+// win_x86:  .def naked_empty
+// win_i686: .def _naked_empty
+//
+// win_x86,win_i686: .scl 2
+// win_x86,win_i686: .type 32
+// win_x86,win_i686: .endef
 //
 // thumb: .type naked_empty, %function
 // thumb: .thumb
@@ -66,10 +71,11 @@ pub unsafe extern "C" fn naked_empty() {
 
 // linux,win: .intel_syntax
 //
-// linux:   .pushsection .text.naked_with_args_and_return,\22ax\22, @progbits
-// macos:   .pushsection __TEXT,__text,regular,pure_instructions
-// win: .pushsection .text.naked_with_args_and_return,\22xr\22
-// thumb:   .pushsection .text.naked_with_args_and_return,\22ax\22, %progbits
+// linux:    .pushsection .text.naked_with_args_and_return,\22ax\22, @progbits
+// macos:    .pushsection __TEXT,__text,regular,pure_instructions
+// win_x86:  .pushsection .text.naked_with_args_and_return,\22xr\22
+// win_i686: .pushsection .text._naked_with_args_and_return,\22xr\22
+// thumb:    .pushsection .text.naked_with_args_and_return,\22ax\22, %progbits
 //
 // CHECK: .balign 4
 //
@@ -81,10 +87,12 @@ pub unsafe extern "C" fn naked_empty() {
 //
 // linux: .type naked_with_args_and_return, @function
 //
-// win: .def naked_with_args_and_return
-// win: .scl 2
-// win: .type 32
-// win: .endef naked_with_args_and_return
+// win_x86:  .def naked_with_args_and_return
+// win_i686: .def _naked_with_args_and_return
+//
+// win_x86,win_i686: .scl 2
+// win_x86,win_i686: .type 32
+// win_x86,win_i686: .endef
 //
 // thumb: .type naked_with_args_and_return, %function
 // thumb: .thumb
@@ -92,7 +100,7 @@ pub unsafe extern "C" fn naked_empty() {
 //
 // CHECK-LABEL: naked_with_args_and_return:
 //
-// linux, win: lea rax, [rdi + rsi]
+// linux, win_x86,win_i686: lea rax, [rdi + rsi]
 // macos: add x0, x0, x1
 // thumb: adds r0, r0, r1
 //
@@ -124,10 +132,10 @@ pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize
     }
 }
 
-// linux:   .pushsection .text.some_different_name,\22ax\22, @progbits
-// macos:   .pushsection .text.some_different_name,regular,pure_instructions
-// win: .pushsection .text.some_different_name,\22xr\22
-// thumb:   .pushsection .text.some_different_name,\22ax\22, %progbits
+// linux:            .pushsection .text.some_different_name,\22ax\22, @progbits
+// macos:            .pushsection .text.some_different_name,regular,pure_instructions
+// win_x86,win_i686: .pushsection .text.some_different_name,\22xr\22
+// thumb:            .pushsection .text.some_different_name,\22ax\22, %progbits
 // CHECK-LABEL: test_link_section:
 #[no_mangle]
 #[naked]
@@ -139,3 +147,19 @@ pub unsafe extern "C" fn test_link_section() {
     #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))]
     naked_asm!("bx lr");
 }
+
+// win_x86:  .def fastcall_cc
+// win_i686: .def @fastcall_cc@4
+//
+// win_x86,win_i686: .scl 2
+// win_x86,win_i686: .type 32
+// win_x86,win_i686: .endef
+//
+// win_x86-LABEL: fastcall_cc:
+// win_i686-LABEL: @fastcall_cc@4:
+#[cfg(target_os = "windows")]
+#[no_mangle]
+#[naked]
+pub unsafe extern "fastcall" fn fastcall_cc(x: i32) -> i32 {
+    naked_asm!("ret");
+}
diff --git a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
index 8d5991872e1..2a672e82970 100644
--- a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
+++ b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
@@ -55,16 +55,16 @@
       bb3: {
           StorageDead(_9);
 -         _0 = AllCopy { a: move _2, b: move _5, c: move _8 };
+-         StorageDead(_10);
 +         _0 = copy (*_1);
++         nop;
           StorageDead(_8);
-          StorageDead(_5);
-          StorageDead(_2);
--         StorageDead(_10);
 -         StorageDead(_7);
--         StorageDead(_4);
-+         nop;
 +         nop;
+          StorageDead(_5);
+-         StorageDead(_4);
 +         nop;
+          StorageDead(_2);
           return;
       }
   }
diff --git a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff
index d0b50c597c4..5f9a8fe9547 100644
--- a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff
+++ b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff
@@ -53,12 +53,12 @@
       bb3: {
           StorageDead(_9);
           _0 = MyThing::<T> { v: move _2, i: move _5, a: move _8 };
-          StorageDead(_8);
-          StorageDead(_5);
-          StorageDead(_2);
           StorageDead(_10);
+          StorageDead(_8);
           StorageDead(_7);
+          StorageDead(_5);
           StorageDead(_4);
+          StorageDead(_2);
           return;
       }
   }
diff --git a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff
index b8f4f348530..0a02c2d4c0f 100644
--- a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff
+++ b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff
@@ -53,12 +53,12 @@
       bb3: {
           StorageDead(_9);
           _0 = MyThing::<T> { v: move _2, i: move _5, a: move _8 };
-          StorageDead(_8);
-          StorageDead(_5);
-          StorageDead(_2);
           StorageDead(_10);
+          StorageDead(_8);
           StorageDead(_7);
+          StorageDead(_5);
           StorageDead(_4);
+          StorageDead(_2);
           return;
       }
   
diff --git a/tests/run-make/core-no-fp-fmt-parse/rmake.rs b/tests/run-make/core-no-fp-fmt-parse/rmake.rs
index 3586922f28e..a790ada40db 100644
--- a/tests/run-make/core-no-fp-fmt-parse/rmake.rs
+++ b/tests/run-make/core-no-fp-fmt-parse/rmake.rs
@@ -5,7 +5,7 @@ use run_make_support::{rustc, source_root};
 
 fn main() {
     rustc()
-        .edition("2021")
+        .edition("2024")
         .arg("-Dwarnings")
         .crate_type("rlib")
         .input(source_root().join("library/core/src/lib.rs"))
diff --git a/tests/ui/macros/std-2024-macros.rs b/tests/ui/macros/std-2024-macros.rs
new file mode 100644
index 00000000000..453c7ee16e5
--- /dev/null
+++ b/tests/ui/macros/std-2024-macros.rs
@@ -0,0 +1,13 @@
+// Tests a small handful of macros in the standard library how they handle the
+// new behavior introduced in 2024 that allows `const{}` expressions.
+
+//@ check-pass
+
+fn main() {
+    assert_eq!(0, const { 0 });
+    assert_eq!(const { 0 }, const { 0 });
+    assert_eq!(const { 0 }, 0);
+
+    let _: Vec<Vec<String>> = vec![const { vec![] }];
+    let _: Vec<Vec<String>> = vec![const { vec![] }; 10];
+}