about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-02-19 20:14:30 +0000
committerbors <bors@rust-lang.org>2025-02-19 20:14:30 +0000
commitf280acf4c743806abbbbcfe65050ac52ec4bdec0 (patch)
tree370ce94df2f479528d6216a3f810e3421a3ebb17
parented49386d3aa3a445a9889707fd405df01723eced (diff)
parent3fc6dfd5edcd7adaec0d971d050156fcd9267d7a (diff)
downloadrust-f280acf4c743806abbbbcfe65050ac52ec4bdec0.tar.gz
rust-f280acf4c743806abbbbcfe65050ac52ec4bdec0.zip
Auto merge of #137284 - matthiaskrgr:rollup-deuhk46, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #127793 (Added project-specific Zed IDE settings)
 - #134995 (Stabilize const_slice_flatten)
 - #136301 (Improve instant docs)
 - #136347 (Add a bullet point to `std::fs::copy`)
 - #136794 (Stabilize file_lock)
 - #137094 (x86_win64 ABI: do not use xmm0 with softfloat ABI)
 - #137227 (docs(dev): Update the feature-gate instructions)
 - #137232 (Don't mention `FromResidual` on bad `?`)
 - #137251 (coverage: Get hole spans from nested items without fully visiting them)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs51
-rw-r--r--compiler/rustc_target/src/callconv/x86_win64.rs16
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs8
-rw-r--r--library/core/src/slice/mod.rs4
-rw-r--r--library/std/src/fs.rs16
-rw-r--r--library/std/src/time.rs10
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs83
-rw-r--r--src/bootstrap/src/core/build_steps/setup/tests.rs21
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md11
-rw-r--r--src/doc/rustc-dev-guide/src/implementing_new_features.md4
-rw-r--r--src/etc/rust_analyzer_zed.json52
-rw-r--r--tests/assembly/x86_64-windows-i128-abi.rs26
-rw-r--r--tests/codegen/i128-x86-callconv.rs38
-rw-r--r--tests/coverage/holes.cov-map31
-rw-r--r--tests/coverage/holes.coverage41
-rw-r--r--tests/coverage/holes.rs33
-rw-r--r--tests/ui/traits/question-mark-result-err-mismatch.rs1
-rw-r--r--tests/ui/traits/question-mark-result-err-mismatch.stderr6
-rw-r--r--tests/ui/try-block/try-block-bad-type.stderr1
-rw-r--r--tests/ui/try-trait/bad-interconversion.stderr1
-rw-r--r--tests/ui/try-trait/issue-32709.stderr1
21 files changed, 330 insertions, 125 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 264995efe8f..1ccae0fd7fe 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -346,35 +346,37 @@ fn extract_hole_spans_from_hir<'tcx>(
     body_span: Span, // Usually `hir_body.value.span`, but not always
     hir_body: &hir::Body<'tcx>,
 ) -> Vec<Span> {
-    struct HolesVisitor<'hir, F> {
-        tcx: TyCtxt<'hir>,
-        visit_hole_span: F,
+    struct HolesVisitor<'tcx> {
+        tcx: TyCtxt<'tcx>,
+        body_span: Span,
+        hole_spans: Vec<Span>,
     }
 
-    impl<'hir, F: FnMut(Span)> Visitor<'hir> for HolesVisitor<'hir, F> {
-        /// - We need `NestedFilter::INTRA = true` so that `visit_item` will be called.
-        /// - Bodies of nested items don't actually get visited, because of the
-        ///   `visit_item` override.
-        /// - For nested bodies that are not part of an item, we do want to visit any
-        ///   items contained within them.
-        type NestedFilter = nested_filter::All;
+    impl<'tcx> Visitor<'tcx> for HolesVisitor<'tcx> {
+        /// We have special handling for nested items, but we still want to
+        /// traverse into nested bodies of things that are not considered items,
+        /// such as "anon consts" (e.g. array lengths).
+        type NestedFilter = nested_filter::OnlyBodies;
 
-        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
+        fn maybe_tcx(&mut self) -> TyCtxt<'tcx> {
             self.tcx
         }
 
-        fn visit_item(&mut self, item: &'hir hir::Item<'hir>) {
-            (self.visit_hole_span)(item.span);
+        /// We override `visit_nested_item` instead of `visit_item` because we
+        /// only need the item's span, not the item itself.
+        fn visit_nested_item(&mut self, id: hir::ItemId) -> Self::Result {
+            let span = self.tcx.def_span(id.owner_id.def_id);
+            self.visit_hole_span(span);
             // Having visited this item, we don't care about its children,
             // so don't call `walk_item`.
         }
 
         // We override `visit_expr` instead of the more specific expression
         // visitors, so that we have direct access to the expression span.
-        fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
+        fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
             match expr.kind {
                 hir::ExprKind::Closure(_) | hir::ExprKind::ConstBlock(_) => {
-                    (self.visit_hole_span)(expr.span);
+                    self.visit_hole_span(expr.span);
                     // Having visited this expression, we don't care about its
                     // children, so don't call `walk_expr`.
                 }
@@ -384,18 +386,17 @@ fn extract_hole_spans_from_hir<'tcx>(
             }
         }
     }
-
-    let mut hole_spans = vec![];
-    let mut visitor = HolesVisitor {
-        tcx,
-        visit_hole_span: |hole_span| {
+    impl HolesVisitor<'_> {
+        fn visit_hole_span(&mut self, hole_span: Span) {
             // Discard any holes that aren't directly visible within the body span.
-            if body_span.contains(hole_span) && body_span.eq_ctxt(hole_span) {
-                hole_spans.push(hole_span);
+            if self.body_span.contains(hole_span) && self.body_span.eq_ctxt(hole_span) {
+                self.hole_spans.push(hole_span);
             }
-        },
-    };
+        }
+    }
+
+    let mut visitor = HolesVisitor { tcx, body_span, hole_spans: vec![] };
 
     visitor.visit_body(hir_body);
-    hole_spans
+    visitor.hole_spans
 }
diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs
index 23ef2cf8284..2ef5127de04 100644
--- a/compiler/rustc_target/src/callconv/x86_win64.rs
+++ b/compiler/rustc_target/src/callconv/x86_win64.rs
@@ -1,11 +1,11 @@
 use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size};
 
 use crate::callconv::{ArgAbi, FnAbi, Reg};
-use crate::spec::HasTargetSpec;
+use crate::spec::{HasTargetSpec, RustcAbi};
 
 // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
 
-pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| {
         match a.layout.backend_repr {
             BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
@@ -24,10 +24,14 @@ pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<
             }
             BackendRepr::Scalar(scalar) => {
                 if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) {
-                    // `i128` is returned in xmm0 by Clang and GCC
-                    // FIXME(#134288): This may change for the `-msvc` targets in the future.
-                    let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) };
-                    a.cast_to(reg);
+                    if cx.target_spec().rustc_abi == Some(RustcAbi::X86Softfloat) {
+                        // Use the native `i128` LLVM type for the softfloat ABI -- in other words, adjust nothing.
+                    } else {
+                        // `i128` is returned in xmm0 by Clang and GCC
+                        // FIXME(#134288): This may change for the `-msvc` targets in the future.
+                        let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) };
+                        a.cast_to(reg);
+                    }
                 } else if a.layout.size.bytes() > 8
                     && !matches!(scalar.primitive(), Primitive::Float(Float::F128))
                 {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 3d89b6ed2f0..ee0ab0dfbb8 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3289,6 +3289,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 let mut parent_trait_pred =
                     self.resolve_vars_if_possible(data.derived.parent_trait_pred);
                 let parent_def_id = parent_trait_pred.def_id();
+                if tcx.is_diagnostic_item(sym::FromResidual, parent_def_id)
+                    && !tcx.features().enabled(sym::try_trait_v2)
+                {
+                    // If `#![feature(try_trait_v2)]` is not enabled, then there's no point on
+                    // talking about `FromResidual<Result<A, B>>`, as the end user has nothing they
+                    // can do about it. As far as they are concerned, `?` is compiler magic.
+                    return;
+                }
                 let self_ty_str =
                     tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
                 let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index ed45e26256e..7b9a76e814a 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -4796,7 +4796,7 @@ impl<T, const N: usize> [[T; N]] {
     /// assert!(empty_slice_of_arrays.as_flattened().is_empty());
     /// ```
     #[stable(feature = "slice_flatten", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
+    #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_flattened(&self) -> &[T] {
         let len = if T::IS_ZST {
             self.len().checked_mul(N).expect("slice len overflow")
@@ -4833,7 +4833,7 @@ impl<T, const N: usize> [[T; N]] {
     /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
     /// ```
     #[stable(feature = "slice_flatten", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
+    #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_flattened_mut(&mut self) -> &mut [T] {
         let len = if T::IS_ZST {
             self.len().checked_mul(N).expect("slice len overflow")
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index c340b43352f..57e235c3efe 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -664,7 +664,6 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -673,7 +672,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "file_lock", issue = "130994")]
+    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
     pub fn lock(&self) -> io::Result<()> {
         self.inner.lock()
     }
@@ -717,7 +716,6 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -726,7 +724,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "file_lock", issue = "130994")]
+    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
     pub fn lock_shared(&self) -> io::Result<()> {
         self.inner.lock_shared()
     }
@@ -775,7 +773,6 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -784,7 +781,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "file_lock", issue = "130994")]
+    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
     pub fn try_lock(&self) -> io::Result<bool> {
         self.inner.try_lock()
     }
@@ -832,7 +829,6 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -841,7 +837,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "file_lock", issue = "130994")]
+    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
     pub fn try_lock_shared(&self) -> io::Result<bool> {
         self.inner.try_lock_shared()
     }
@@ -869,7 +865,6 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -879,7 +874,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "file_lock", issue = "130994")]
+    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
     pub fn unlock(&self) -> io::Result<()> {
         self.inner.unlock()
     }
@@ -2531,6 +2526,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// * `from` does not exist.
 /// * The current process does not have the permission rights to read
 ///   `from` or write `to`.
+/// * The parent directory of `to` doesn't exist.
 ///
 /// # Examples
 ///
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index 88b3e9e0ceb..5ab71413586 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -93,11 +93,17 @@ use crate::sys_common::{FromInner, IntoInner};
 /// use std::time::{Instant, Duration};
 ///
 /// let now = Instant::now();
-/// let max_seconds = u64::MAX / 1_000_000_000;
-/// let duration = Duration::new(max_seconds, 0);
+/// let days_per_10_millennia = 365_2425;
+/// let solar_seconds_per_day = 60 * 60 * 24;
+/// let millenium_in_solar_seconds = 31_556_952_000;
+/// assert_eq!(millenium_in_solar_seconds, days_per_10_millennia * solar_seconds_per_day / 10);
+///
+/// let duration = Duration::new(millenium_in_solar_seconds, 0);
 /// println!("{:?}", now + duration);
 /// ```
 ///
+/// For cross-platform code, you can comfortably use durations of up to around one hundred years.
+///
 /// # Underlying System calls
 ///
 /// The following system calls are [currently] being used by `now()` to find out
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index fbd0dc3ec30..f25dfaab0f1 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -523,19 +523,31 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
 /// Handles editor-specific setup differences
 #[derive(Clone, Debug, Eq, PartialEq)]
 enum EditorKind {
-    Vscode,
-    Vim,
     Emacs,
     Helix,
+    Vim,
+    VsCode,
+    Zed,
 }
 
 impl EditorKind {
+    // Used in `./tests.rs`.
+    #[allow(dead_code)]
+    pub const ALL: &[EditorKind] = &[
+        EditorKind::Emacs,
+        EditorKind::Helix,
+        EditorKind::Vim,
+        EditorKind::VsCode,
+        EditorKind::Zed,
+    ];
+
     fn prompt_user() -> io::Result<Option<EditorKind>> {
         let prompt_str = "Available editors:
-1. vscode
-2. vim
-3. emacs
-4. helix
+1. Emacs
+2. Helix
+3. Vim
+4. VS Code
+5. Zed
 
 Select which editor you would like to set up [default: None]: ";
 
@@ -543,28 +555,41 @@ Select which editor you would like to set up [default: None]: ";
         loop {
             print!("{}", prompt_str);
             io::stdout().flush()?;
-            input.clear();
             io::stdin().read_line(&mut input)?;
-            match input.trim().to_lowercase().as_str() {
-                "1" | "vscode" => return Ok(Some(EditorKind::Vscode)),
-                "2" | "vim" => return Ok(Some(EditorKind::Vim)),
-                "3" | "emacs" => return Ok(Some(EditorKind::Emacs)),
-                "4" | "helix" => return Ok(Some(EditorKind::Helix)),
-                "" => return Ok(None),
+
+            let mut modified_input = input.to_lowercase();
+            modified_input.retain(|ch| !ch.is_whitespace());
+            match modified_input.as_str() {
+                "1" | "emacs" => return Ok(Some(EditorKind::Emacs)),
+                "2" | "helix" => return Ok(Some(EditorKind::Helix)),
+                "3" | "vim" => return Ok(Some(EditorKind::Vim)),
+                "4" | "vscode" => return Ok(Some(EditorKind::VsCode)),
+                "5" | "zed" => return Ok(Some(EditorKind::Zed)),
+                "" | "none" => return Ok(None),
                 _ => {
                     eprintln!("ERROR: unrecognized option '{}'", input.trim());
                     eprintln!("NOTE: press Ctrl+C to exit");
                 }
-            };
+            }
+
+            input.clear();
         }
     }
 
     /// A list of historical hashes of each LSP settings file
     /// New entries should be appended whenever this is updated so we can detect
     /// outdated vs. user-modified settings files.
-    fn hashes(&self) -> Vec<&str> {
+    fn hashes(&self) -> &'static [&'static str] {
         match self {
-            EditorKind::Vscode | EditorKind::Vim => vec![
+            EditorKind::Emacs => &[
+                "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
+                "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
+            ],
+            EditorKind::Helix => &[
+                "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233",
+                "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040",
+            ],
+            EditorKind::Vim | EditorKind::VsCode => &[
                 "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8",
                 "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922",
                 "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0",
@@ -576,12 +601,8 @@ Select which editor you would like to set up [default: None]: ";
                 "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
                 "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d",
             ],
-            EditorKind::Emacs => vec![
-                "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
-                "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
-            ],
-            EditorKind::Helix => {
-                vec!["2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233"]
+            EditorKind::Zed => {
+                &["bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c"]
             }
         }
     }
@@ -592,29 +613,31 @@ Select which editor you would like to set up [default: None]: ";
 
     fn settings_short_path(&self) -> PathBuf {
         self.settings_folder().join(match self {
-            EditorKind::Vscode => "settings.json",
-            EditorKind::Vim => "coc-settings.json",
             EditorKind::Emacs => ".dir-locals.el",
             EditorKind::Helix => "languages.toml",
+            EditorKind::Vim => "coc-settings.json",
+            EditorKind::VsCode | EditorKind::Zed => "settings.json",
         })
     }
 
     fn settings_folder(&self) -> PathBuf {
         match self {
-            EditorKind::Vscode => PathBuf::from(".vscode"),
-            EditorKind::Vim => PathBuf::from(".vim"),
             EditorKind::Emacs => PathBuf::new(),
             EditorKind::Helix => PathBuf::from(".helix"),
+            EditorKind::Vim => PathBuf::from(".vim"),
+            EditorKind::VsCode => PathBuf::from(".vscode"),
+            EditorKind::Zed => PathBuf::from(".zed"),
         }
     }
 
-    fn settings_template(&self) -> &str {
+    fn settings_template(&self) -> &'static str {
         match self {
-            EditorKind::Vscode | EditorKind::Vim => {
-                include_str!("../../../../etc/rust_analyzer_settings.json")
-            }
             EditorKind::Emacs => include_str!("../../../../etc/rust_analyzer_eglot.el"),
             EditorKind::Helix => include_str!("../../../../etc/rust_analyzer_helix.toml"),
+            EditorKind::Vim | EditorKind::VsCode => {
+                include_str!("../../../../etc/rust_analyzer_settings.json")
+            }
+            EditorKind::Zed => include_str!("../../../../etc/rust_analyzer_zed.json"),
         }
     }
 
diff --git a/src/bootstrap/src/core/build_steps/setup/tests.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs
index f3d4b6aa4db..e8f83ff75e4 100644
--- a/src/bootstrap/src/core/build_steps/setup/tests.rs
+++ b/src/bootstrap/src/core/build_steps/setup/tests.rs
@@ -5,13 +5,16 @@ use crate::utils::helpers::hex_encode;
 
 #[test]
 fn check_matching_settings_hash() {
-    let editor = EditorKind::Vscode;
-    let mut hasher = sha2::Sha256::new();
-    hasher.update(&editor.settings_template());
-    let hash = hex_encode(hasher.finalize().as_slice());
-    assert_eq!(
-        &hash,
-        editor.hashes().last().unwrap(),
-        "Update `EditorKind::hashes()` with the new hash of `src/etc/rust_analyzer_settings.json`"
-    );
+    for editor in EditorKind::ALL {
+        let mut hasher = sha2::Sha256::new();
+        hasher.update(&editor.settings_template());
+        let hash = hex_encode(hasher.finalize().as_slice());
+        assert_eq!(
+            &hash,
+            editor.hashes().last().unwrap(),
+            "Update `EditorKind::hashes()` with the new hash of `{}` for `EditorKind::{:?}`",
+            editor.settings_template(),
+            editor,
+        );
+    }
 }
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 2c6c3fe1df8..5c041d6cb70 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -154,6 +154,16 @@ You can run `./x setup editor` and select `helix`, which will prompt you to
 create `languages.toml` with the recommended configuration for Helix. The
 recommended settings live at [`src/etc/rust_analyzer_helix.toml`].
 
+### Zed
+
+Zed comes with built-in LSP and rust-analyzer support.
+It can be configured through `.zed/settings.json`, as described
+[here](https://zed.dev/docs/configuring-languages). Selecting `zed`
+in `./x setup editor` will prompt you to create a `.zed/settings.json`
+file which will configure Zed with the recommended configuration. The
+recommended `rust-analyzer` settings live
+at [`src/etc/rust_analyzer_zed.json`].
+
 ## Check, check, and check again
 
 When doing simple refactoring, it can be useful to run `./x check`
@@ -381,4 +391,5 @@ load this completion.
 [`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json
 [`src/etc/rust_analyzer_eglot.el`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_eglot.el
 [`src/etc/rust_analyzer_helix.toml`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_helix.toml
+[`src/etc/rust_analyzer_zed.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_zed.json
 [`src/etc/pre-push.sh`]: https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh
diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md
index 5b67ccd7f4c..fda38ef4fc0 100644
--- a/src/doc/rustc-dev-guide/src/implementing_new_features.md
+++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md
@@ -167,9 +167,7 @@ a new unstable feature:
 
 1. Prevent usage of the new feature unless the feature gate is set.
    You can check it in most places in the compiler using the
-   expression `tcx.features().$feature_name` (or
-   `sess.features_untracked().$feature_name` if the
-   tcx is unavailable)
+   expression `tcx.features().$feature_name()`
 
     If the feature gate is not set, you should either maintain
     the pre-feature behavior or raise an error, depending on
diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json
new file mode 100644
index 00000000000..469ea050621
--- /dev/null
+++ b/src/etc/rust_analyzer_zed.json
@@ -0,0 +1,52 @@
+{
+  "lsp": {
+    "rust-analyzer": {
+      "initialization_options": {
+        "cargo": {
+          "buildScripts": {
+            "enable": true,
+            "invocationLocation": "root",
+            "invocationStrategy": "once",
+            "overrideCommand": ["python3", "x.py", "check", "--json-output"]
+          },
+          "extraEnv": {
+            "RUSTC_BOOTSTRAP": "1"
+          },
+          "sysrootSrc": "./library"
+        },
+        "check": {
+          "invocationLocation": "root",
+          "invocationStrategy": "once",
+          "overrideCommand": ["python3", "x.py", "check", "--json-output"]
+        },
+        "linkedProjects": [
+          "Cargo.toml",
+          "library/Cargo.toml",
+          "src/tools/x/Cargo.toml",
+          "src/bootstrap/Cargo.toml",
+          "src/tools/rust-analyzer/Cargo.toml",
+          "compiler/rustc_codegen_cranelift/Cargo.toml",
+          "compiler/rustc_codegen_gcc/Cargo.toml"
+        ],
+        "procMacro": {
+            "enable": true,
+            "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv"
+        },
+        "rustc": {
+          "source": "./Cargo.toml"
+        },
+        "rustfmt": {
+          "overrideCommand": [
+            "${workspaceFolder}/build/host/rustfmt/bin/rustfmt",
+            "--edition=2021"
+          ]
+        },
+        "server": {
+          "extraEnv": {
+            "RUSTUP_TOOLCHAIN": "nightly"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/tests/assembly/x86_64-windows-i128-abi.rs b/tests/assembly/x86_64-windows-i128-abi.rs
new file mode 100644
index 00000000000..d2aefb7daa6
--- /dev/null
+++ b/tests/assembly/x86_64-windows-i128-abi.rs
@@ -0,0 +1,26 @@
+//@ assembly-output: emit-asm
+//@ add-core-stubs
+//@ revisions: msvc softfloat
+//@ compile-flags: -Copt-level=3
+//@[msvc] compile-flags: --target x86_64-pc-windows-msvc
+//@[msvc] needs-llvm-components: x86
+//@[softfloat] compile-flags: --target x86_64-unknown-uefi
+//@[softfloat] needs-llvm-components: x86
+
+#![feature(no_core)]
+#![no_core]
+#![crate_type = "lib"]
+
+extern crate minicore;
+use minicore::*;
+
+// CHECK-LABEL: ret_i128
+// Hardfloat targets return via xmm0, softfloat targets via rax and rdx.
+// msvc: movaps {{.*}}, %xmm0
+// softfloat: movq (%[[INPUT:.*]]), %rax
+// softfloat-NEXT: movq 8(%[[INPUT]]), %rdx
+// CHECK-NEXT: retq
+#[no_mangle]
+pub extern "C" fn ret_i128(x: &i128) -> i128 {
+    *x
+}
diff --git a/tests/codegen/i128-x86-callconv.rs b/tests/codegen/i128-x86-callconv.rs
index 9a9c9002fc0..41c30c09c1a 100644
--- a/tests/codegen/i128-x86-callconv.rs
+++ b/tests/codegen/i128-x86-callconv.rs
@@ -4,13 +4,18 @@
 //@ compile-flags: -Copt-level=1
 
 //@ add-core-stubs
-//@ revisions: MSVC MINGW
+//@ revisions: MSVC MINGW softfloat
 //@ [MSVC] needs-llvm-components: x86
-//@ [MINGW] needs-llvm-components: x86
 //@ [MSVC] compile-flags: --target x86_64-pc-windows-msvc
-//@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu
+// Use `WIN` as a common prefix for MSVC and MINGW but *not* the softfloat test.
 //@ [MSVC] filecheck-flags: --check-prefix=WIN
+//@ [MINGW] needs-llvm-components: x86
+//@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu
 //@ [MINGW] filecheck-flags: --check-prefix=WIN
+// The `x86_64-unknown-uefi` target also uses the Windows calling convention,
+// but does not have SSE registers available.
+//@ [softfloat] needs-llvm-components: x86
+//@ [softfloat] compile-flags: --target x86_64-unknown-uefi
 
 #![crate_type = "lib"]
 #![no_std]
@@ -28,24 +33,26 @@ extern "C" {
 pub extern "C" fn pass(_arg0: u32, arg1: i128) {
     // CHECK-LABEL: @pass(
     // i128 is passed indirectly on Windows. It should load the pointer to the stack and pass
-    // a pointer to that allocation.
-    // WIN-SAME: %_arg0, ptr{{.*}} %arg1)
-    // WIN: [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16
-    // WIN: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
-    // WIN: store i128 [[LOADED]], ptr [[PASS]]
-    // WIN: call void @extern_call
+    // a pointer to that allocation. The softfloat ABI works the same.
+    // CHECK-SAME: %_arg0, ptr{{.*}} %arg1)
+    // CHECK: [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16
+    // CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
+    // CHECK: store i128 [[LOADED]], ptr [[PASS]]
+    // CHECK: call void @extern_call
     unsafe { extern_call(arg1) };
 }
 
 // Check that we produce the correct return ABI
 #[no_mangle]
 pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 {
-    // CHECK-LABEL: @ret(
+    // WIN-LABEL: @ret(
     // i128 is returned in xmm0 on Windows
     // FIXME(#134288): This may change for the `-msvc` targets in the future.
     // WIN-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1)
     // WIN: [[LOADED:%[_0-9]+]] = load <16 x i8>, ptr %arg1
     // WIN-NEXT: ret <16 x i8> [[LOADED]]
+    // The softfloat ABI returns this indirectly.
+    // softfloat-LABEL: i128 @ret(i32{{.*}} %_arg0, ptr{{.*}} %arg1)
     arg1
 }
 
@@ -57,6 +64,7 @@ pub extern "C" fn forward(dst: *mut i128) {
     // WIN: [[RETURNED:%[_0-9]+]] = tail call <16 x i8> @extern_ret()
     // WIN: store <16 x i8> [[RETURNED]], ptr %dst
     // WIN: ret void
+    // softfloat: [[RETURNED:%[_0-9]+]] = tail call {{.*}}i128 @extern_ret()
     unsafe { *dst = extern_ret() };
 }
 
@@ -70,10 +78,10 @@ struct RetAggregate {
 pub extern "C" fn ret_aggregate(_arg0: u32, arg1: i128) -> RetAggregate {
     // CHECK-LABEL: @ret_aggregate(
     // Aggregates should also be returned indirectly
-    // WIN-SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
-    // WIN: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
-    // WIN: [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
-    // WIN: store i128 [[LOADED]], ptr [[GEP]]
-    // WIN: ret void
+    // CHECK-SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
+    // CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
+    // CHECK: [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
+    // CHECK: store i128 [[LOADED]], ptr [[GEP]]
+    // CHECK: ret void
     RetAggregate { a: 1, b: arg1 }
 }
diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map
index 3c740d80ea0..3deacbc8e12 100644
--- a/tests/coverage/holes.cov-map
+++ b/tests/coverage/holes.cov-map
@@ -1,52 +1,57 @@
 Function name: <holes::main::MyStruct>::_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 25, 09, 00, 1d]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 37, 9) to (start + 0, 29)
+- Code(Zero) at (prev + 43, 9) to (start + 0, 29)
 Highest counter ID seen: (none)
 
 Function name: holes::main
-Raw bytes (44): 0x[01, 01, 00, 08, 01, 08, 01, 06, 11, 01, 0f, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 01, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 12, 01, 05, 05, 00, 12, 01, 07, 09, 00, 11, 01, 09, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 04, 05, 00, 12, 01, 04, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 0c, 0d, 01, 0f, 0e, 05, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 8, 1) to (start + 6, 17)
-- Code(Counter(0)) at (prev + 15, 5) to (start + 0, 18)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 18)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 18)
 - Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
 - Code(Counter(0)) at (prev + 7, 5) to (start + 0, 18)
 - Code(Counter(0)) at (prev + 6, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
 - Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15)
 - Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15)
-- Code(Counter(0)) at (prev + 10, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 12, 13)
+- Code(Counter(0)) at (prev + 15, 14) to (start + 5, 2)
 Highest counter ID seen: c0
 
 Function name: holes::main::_unused_fn (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 5) to (start + 0, 23)
+- Code(Zero) at (prev + 31, 5) to (start + 0, 23)
 Highest counter ID seen: (none)
 
 Function name: holes::main::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 18, 9) to (start + 2, 10)
+- Code(Zero) at (prev + 24, 9) to (start + 2, 10)
 Highest counter ID seen: (none)
 
 Function name: holes::main::{closure#1} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 3d, 09, 02, 0a]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 61, 9) to (start + 2, 10)
+- Code(Zero) at (prev + 75, 9) to (start + 2, 10)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage
index 6e65435f7e3..1b45c12156a 100644
--- a/tests/coverage/holes.coverage
+++ b/tests/coverage/holes.coverage
@@ -7,10 +7,16 @@
    LL|       |
    LL|      1|fn main() {
    LL|      1|    black_box(());
-   LL|      1|
-   LL|      1|    // Splitting this across multiple lines makes it easier to see where the
-   LL|      1|    // coverage mapping regions begin and end.
-   LL|      1|    #[rustfmt::skip]
+   LL|       |
+   LL|       |    static MY_STATIC: () = ();
+   LL|       |
+   LL|      1|    black_box(());
+   LL|       |
+   LL|       |    const MY_CONST: () = ();
+   LL|       |
+   LL|       |    // Splitting this across multiple lines makes it easier to see where the
+   LL|       |    // coverage mapping regions begin and end.
+   LL|       |    #[rustfmt::skip]
    LL|      1|    let _closure =
    LL|       |        |
    LL|       |            _arg: (),
@@ -39,6 +45,14 @@
    LL|       |
    LL|      1|    black_box(());
    LL|       |
+   LL|       |    trait MyTrait {}
+   LL|       |
+   LL|      1|    black_box(());
+   LL|       |
+   LL|       |    impl MyTrait for MyStruct {}
+   LL|       |
+   LL|      1|    black_box(());
+   LL|       |
    LL|       |    macro_rules! _my_macro {
    LL|       |        () => {};
    LL|       |    }
@@ -64,5 +78,24 @@
    LL|       |        ;
    LL|       |
    LL|      1|    black_box(());
+   LL|      1|
+   LL|      1|    // This tests the edge case of a const block nested inside an "anon const",
+   LL|      1|    // such as the length of an array literal. Handling this case requires
+   LL|      1|    // `nested_filter::OnlyBodies` or equivalent.
+   LL|      1|    #[rustfmt::skip]
+   LL|      1|    let _const_block_inside_anon_const =
+   LL|      1|        [
+   LL|      1|            0
+   LL|      1|            ;
+   LL|      1|            7
+   LL|      1|            +
+   LL|      1|            const
+   LL|       |            {
+   LL|       |                3
+   LL|      1|            }
+   LL|      1|        ]
+   LL|      1|        ;
+   LL|      1|
+   LL|      1|    black_box(());
    LL|      1|}
 
diff --git a/tests/coverage/holes.rs b/tests/coverage/holes.rs
index b3a71e759c8..7f6671772c3 100644
--- a/tests/coverage/holes.rs
+++ b/tests/coverage/holes.rs
@@ -8,6 +8,12 @@ use core::hint::black_box;
 fn main() {
     black_box(());
 
+    static MY_STATIC: () = ();
+
+    black_box(());
+
+    const MY_CONST: () = ();
+
     // Splitting this across multiple lines makes it easier to see where the
     // coverage mapping regions begin and end.
     #[rustfmt::skip]
@@ -39,6 +45,14 @@ fn main() {
 
     black_box(());
 
+    trait MyTrait {}
+
+    black_box(());
+
+    impl MyTrait for MyStruct {}
+
+    black_box(());
+
     macro_rules! _my_macro {
         () => {};
     }
@@ -64,4 +78,23 @@ fn main() {
         ;
 
     black_box(());
+
+    // This tests the edge case of a const block nested inside an "anon const",
+    // such as the length of an array literal. Handling this case requires
+    // `nested_filter::OnlyBodies` or equivalent.
+    #[rustfmt::skip]
+    let _const_block_inside_anon_const =
+        [
+            0
+            ;
+            7
+            +
+            const
+            {
+                3
+            }
+        ]
+        ;
+
+    black_box(());
 }
diff --git a/tests/ui/traits/question-mark-result-err-mismatch.rs b/tests/ui/traits/question-mark-result-err-mismatch.rs
index 0ca18b5b0dd..df1d5105a34 100644
--- a/tests/ui/traits/question-mark-result-err-mismatch.rs
+++ b/tests/ui/traits/question-mark-result-err-mismatch.rs
@@ -1,3 +1,4 @@
+#![feature(try_trait_v2)]
 fn foo() -> Result<String, String> { //~ NOTE expected `String` because of this
     let test = String::from("one,two");
     let x = test
diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr
index bad325a6720..0f83c9e73a3 100644
--- a/tests/ui/traits/question-mark-result-err-mismatch.stderr
+++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `?` couldn't convert the error to `String`
-  --> $DIR/question-mark-result-err-mismatch.rs:14:22
+  --> $DIR/question-mark-result-err-mismatch.rs:15:22
    |
 LL |   fn foo() -> Result<String, String> {
    |               ---------------------- expected `String` because of this
@@ -17,7 +17,7 @@ LL |           .map(|()| "")?;
    = note: required for `Result<String, String>` to implement `FromResidual<Result<Infallible, ()>>`
 
 error[E0277]: `?` couldn't convert the error to `String`
-  --> $DIR/question-mark-result-err-mismatch.rs:28:25
+  --> $DIR/question-mark-result-err-mismatch.rs:29:25
    |
 LL | fn bar() -> Result<(), String> {
    |             ------------------ expected `String` because of this
@@ -40,7 +40,7 @@ LL |         .map_err(|_| ())?;
    = note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
 
 error[E0277]: `?` couldn't convert the error to `String`
-  --> $DIR/question-mark-result-err-mismatch.rs:48:11
+  --> $DIR/question-mark-result-err-mismatch.rs:49:11
    |
 LL |   fn baz() -> Result<String, String> {
    |               ---------------------- expected `String` because of this
diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr
index c67ad762a83..818ab499306 100644
--- a/tests/ui/try-block/try-block-bad-type.stderr
+++ b/tests/ui/try-block/try-block-bad-type.stderr
@@ -10,7 +10,6 @@ LL |         Err("")?;
    = help: the trait `From<&str>` is not implemented for `TryFromSliceError`
            but trait `From<Infallible>` is implemented for it
    = help: for that trait implementation, expected `Infallible`, found `&str`
-   = note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
 
 error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
   --> $DIR/try-block-bad-type.rs:12:9
diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr
index bb5e5646ad2..45422be946e 100644
--- a/tests/ui/try-trait/bad-interconversion.stderr
+++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -12,7 +12,6 @@ LL |     Ok(Err(123_i32)?)
    = help: the following other types implement trait `From<T>`:
              `u8` implements `From<Char>`
              `u8` implements `From<bool>`
-   = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
 
 error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
   --> $DIR/bad-interconversion.rs:9:12
diff --git a/tests/ui/try-trait/issue-32709.stderr b/tests/ui/try-trait/issue-32709.stderr
index 475bd1ff3ac..20454e12de5 100644
--- a/tests/ui/try-trait/issue-32709.stderr
+++ b/tests/ui/try-trait/issue-32709.stderr
@@ -19,7 +19,6 @@ LL |     Err(5)?;
              `(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
              `(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
            and 4 others
-   = note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
 
 error: aborting due to 1 previous error