diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 9409057d4847e..60b343afbed9c 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -49,12 +49,11 @@ impl<K: Ord, V> SortedMap<K, V> {
     }
 
     #[inline]
-    pub fn insert(&mut self, key: K, mut value: V) -> Option<V> {
+    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
         match self.lookup_index_for(&key) {
             Ok(index) => {
                 let slot = unsafe { self.data.get_unchecked_mut(index) };
-                mem::swap(&mut slot.1, &mut value);
-                Some(value)
+                Some(mem::replace(&mut slot.1, value))
             }
             Err(index) => {
                 self.data.insert(index, (key, value));
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index e1e3bcc05e74b..d313e8e012f20 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -727,7 +727,7 @@ where
 }
 
 /// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking
-fn into_range_unchecked(
+pub(crate) fn into_range_unchecked(
     len: usize,
     (start, end): (ops::Bound<usize>, ops::Bound<usize>),
 ) -> ops::Range<usize> {
@@ -747,7 +747,7 @@ fn into_range_unchecked(
 
 /// Convert pair of `ops::Bound`s into `ops::Range`.
 /// Returns `None` on overflowing indices.
-fn into_range(
+pub(crate) fn into_range(
     len: usize,
     (start, end): (ops::Bound<usize>, ops::Bound<usize>),
 ) -> Option<ops::Range<usize>> {
@@ -772,7 +772,7 @@ fn into_range(
 
 /// Convert pair of `ops::Bound`s into `ops::Range`.
 /// Panics on overflowing indices.
-fn into_slice_range(
+pub(crate) fn into_slice_range(
     len: usize,
     (start, end): (ops::Bound<usize>, ops::Bound<usize>),
 ) -> ops::Range<usize> {
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 4f13ea9790d87..d95662afddd46 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -38,7 +38,7 @@ pub mod sort;
 
 mod ascii;
 mod cmp;
-mod index;
+pub(crate) mod index;
 mod iter;
 mod raw;
 mod rotate;
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 1d52335f28ebf..49f9f6d4ad1e3 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -252,6 +252,58 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
     }
 }
 
+/// Implements substring slicing for arbitrary bounds.
+///
+/// Returns a slice of the given string bounded by the byte indices
+/// provided by each bound.
+///
+/// This operation is *O*(1).
+///
+/// # Panics
+///
+/// Panics if `begin` or `end` (if it exists and once adjusted for
+/// inclusion/exclusion) does not point to the starting byte offset of
+/// a character (as defined by `is_char_boundary`), if `begin > end`, or if
+/// `end > len`.
+#[stable(feature = "slice_index_str_with_ops_bound_pair", since = "CURRENT_RUSTC_VERSION")]
+unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) {
+    type Output = str;
+
+    #[inline]
+    fn get(self, slice: &str) -> Option<&str> {
+        crate::slice::index::into_range(slice.len(), self)?.get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut str> {
+        crate::slice::index::into_range(slice.len(), self)?.get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const str {
+        let len = (slice as *const [u8]).len();
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut str {
+        let len = (slice as *mut [u8]).len();
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked_mut(slice) }
+    }
+
+    #[inline]
+    fn index(self, slice: &str) -> &str {
+        crate::slice::index::into_slice_range(slice.len(), self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut str {
+        crate::slice::index::into_slice_range(slice.len(), self).index_mut(slice)
+    }
+}
+
 /// Implements substring slicing with syntax `&self[.. end]` or `&mut
 /// self[.. end]`.
 ///
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 81b88d5de98b2..d8718d26848ca 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -24,6 +24,7 @@ use crate::util::{self, exe, output, t, up_to_date};
 use crate::{CLang, GitRepo, Kind};
 
 use build_helper::ci::CiEnv;
+use build_helper::git::get_git_merge_base;
 
 #[derive(Clone)]
 pub struct LlvmResult {
@@ -128,13 +129,19 @@ pub fn prebuilt_llvm_config(
 /// This retrieves the LLVM sha we *want* to use, according to git history.
 pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
     let llvm_sha = if is_git {
+        // We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we
+        // walk back further to the last bors merge commit that actually changed LLVM. The first
+        // step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD`
+        // in that case.
+        let closest_upstream =
+            get_git_merge_base(Some(&config.src)).unwrap_or_else(|_| "HEAD".into());
         let mut rev_list = config.git();
         rev_list.args(&[
             PathBuf::from("rev-list"),
             format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
             "-n1".into(),
             "--first-parent".into(),
-            "HEAD".into(),
+            closest_upstream.into(),
             "--".into(),
             config.src.join("src/llvm-project"),
             config.src.join("src/bootstrap/download-ci-llvm-stamp"),
diff --git a/src/doc/reference b/src/doc/reference
index 1ea0178266b3f..9cd5c5a6ccbd4 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 1ea0178266b3f3f613b0fabdaf16a83961c99cdb
+Subproject commit 9cd5c5a6ccbd4c07c65ab5c69a53286280308c95
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index 8a87926a985ce..07e0df2f006e5 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit 8a87926a985ce32ca1fad1be4008ee161a0b91eb
+Subproject commit 07e0df2f006e59d171c6bf3cafa9d61dbeb520d8
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
index b5a12d95e32ae..24eebb6df96d0 160000
--- a/src/doc/rustc-dev-guide
+++ b/src/doc/rustc-dev-guide
@@ -1 +1 @@
-Subproject commit b5a12d95e32ae53791cc6ab44417774667ed2ac6
+Subproject commit 24eebb6df96d037aad285e4f7793bd0393a66878
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 22ff51489af02..4448dac00a09b 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -101,7 +101,7 @@ target | notes
 `x86_64-unknown-freebsd` | 64-bit FreeBSD
 `x86_64-unknown-illumos` | illumos
 `x86_64-unknown-linux-musl` | 64-bit Linux with MUSL
-`x86_64-unknown-netbsd` | NetBSD/amd64
+[`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64
 
 ## Tier 2
 
@@ -128,7 +128,7 @@ target | std | notes
 `aarch64-apple-ios` | ✓ | ARM64 iOS
 [`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ | Apple iOS Simulator on ARM64
 `aarch64-fuchsia` | ✓ | Alias for `aarch64-unknown-fuchsia`
-`aarch64-unknown-fuchsia` | ✓ | ARM64 Fuchsia
+[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia
 [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android
 `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
 `aarch64-unknown-none` | * | Bare ARM64, hardfloat
@@ -159,7 +159,7 @@ target | std | notes
 `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL
 `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL
 `mipsel-unknown-linux-musl` | ✓ | MIPS (LE) Linux with MUSL
-`nvptx64-nvidia-cuda` | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
+[`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
 `riscv32i-unknown-none-elf` | * | Bare RISC-V (RV32I ISA)
 `riscv32imac-unknown-none-elf` | * | Bare RISC-V (RV32IMAC ISA)
 `riscv32imc-unknown-none-elf` | * | Bare RISC-V (RV32IMC ISA)
@@ -183,7 +183,7 @@ target | std | notes
 `x86_64-apple-ios` | ✓ | 64-bit x86 iOS
 [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
 `x86_64-fuchsia` | ✓ | Alias for `x86_64-unknown-fuchsia`
-`x86_64-unknown-fuchsia` | ✓ | 64-bit Fuchsia
+[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia
 [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android
 `x86_64-pc-solaris` | ✓ | 64-bit Solaris 10/11, illumos
 `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
@@ -337,6 +337,6 @@ target | std | host | notes
 `x86_64-uwp-windows-gnu` | ✓ |  |
 `x86_64-uwp-windows-msvc` | ✓ |  |
 `x86_64-wrs-vxworks` | ? |  |
-`x86_64h-apple-darwin` | ✓ | ✓ | macOS with late-gen Intel (at least Haswell)
+[`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell)
 
 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md
index 6bdb3ae26ace8..f4d759673700d 100644
--- a/src/doc/style-guide/src/README.md
+++ b/src/doc/style-guide/src/README.md
@@ -36,10 +36,10 @@ options.
 
 ### Indentation and line width
 
-* Use spaces, not tabs.
-* Each level of indentation must be 4 spaces (that is, all indentation
+- Use spaces, not tabs.
+- Each level of indentation must be 4 spaces (that is, all indentation
   outside of string literals and comments must be a multiple of 4).
-* The maximum width for a line is 100 characters.
+- The maximum width for a line is 100 characters.
 
 #### Block indent
 
@@ -100,10 +100,12 @@ fn baz() {}
 ```
 
 ### [Module-level items](items.md)
+
 ### [Statements](statements.md)
+
 ### [Expressions](expressions.md)
-### [Types](types.md)
 
+### [Types](types.md)
 
 ### Comments
 
diff --git a/src/doc/style-guide/src/SUMMARY.md b/src/doc/style-guide/src/SUMMARY.md
index 606485bfb6c7e..64540c3997cda 100644
--- a/src/doc/style-guide/src/SUMMARY.md
+++ b/src/doc/style-guide/src/SUMMARY.md
@@ -9,4 +9,5 @@
 - [Other style advice](advice.md)
 - [`Cargo.toml` conventions](cargo.md)
 - [Guiding principles and rationale](principles.md)
+- [Rust style editions](editions.md)
 - [Nightly-only syntax](nightly.md)
diff --git a/src/doc/style-guide/src/advice.md b/src/doc/style-guide/src/advice.md
index 9a617be509c38..65cf8cb6e909c 100644
--- a/src/doc/style-guide/src/advice.md
+++ b/src/doc/style-guide/src/advice.md
@@ -18,16 +18,16 @@ if y {
 
 ## Names
 
- * Types shall be `UpperCamelCase`,
- * Enum variants shall be `UpperCamelCase`,
- * Struct fields shall be `snake_case`,
- * Function and method names shall be `snake_case`,
- * Local variables shall be `snake_case`,
- * Macro names shall be `snake_case`,
- * Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`.
- * When a name is forbidden because it is a reserved word (such as `crate`),
-   either use a raw identifier (`r#crate`) or use a trailing underscore
-   (`crate_`). Don't misspell the word (`krate`).
+- Types shall be `UpperCamelCase`,
+- Enum variants shall be `UpperCamelCase`,
+- Struct fields shall be `snake_case`,
+- Function and method names shall be `snake_case`,
+- Local variables shall be `snake_case`,
+- Macro names shall be `snake_case`,
+- Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`.
+- When a name is forbidden because it is a reserved word (such as `crate`),
+  either use a raw identifier (`r#crate`) or use a trailing underscore
+  (`crate_`). Don't misspell the word (`krate`).
 
 ### Modules
 
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
new file mode 100644
index 0000000000000..5c67a185b8ffa
--- /dev/null
+++ b/src/doc/style-guide/src/editions.md
@@ -0,0 +1,46 @@
+# Rust style editions
+
+The default Rust style evolves over time, as Rust does. However, to avoid
+breaking established code style, and CI jobs checking code style, changes to
+the default Rust style only appear in *style editions*.
+
+Code written in a given
+[Rust edition](https://doc.rust-lang.org/edition-guide/)
+uses the corresponding Rust style edition by default. To make it easier to
+migrate code style separately from the semantic changes between Rust editions,
+formatting tools such as `rustfmt` allow updating the style edition separately
+from the Rust edition.
+
+The current version of the style guide describes the latest Rust style edition.
+Each distinct past style will have a corresponding archived version of the
+style guide.
+
+Note that archived versions of the style guide do not document formatting for
+newer Rust constructs that did not exist at the time that version of the style
+guide was archived. However, each style edition will still format all
+constructs valid in that Rust edition, with the style of newer constructs
+coming from the first subsequent style edition providing formatting rules for
+that construct (without any of the systematic/global changes from that style
+edition).
+
+Not all Rust editions have corresponding changes to the Rust style. For
+instance, Rust 2015, Rust 2018, and Rust 2021 all use the same style edition.
+
+## Rust 2024 style edition
+
+This style guide describes the Rust 2024 style edition. The Rust 2024 style
+edition is currently nightly-only and may change before the release of Rust
+2024.
+
+For a full history of changes in the Rust 2024 style edition, see the git
+history of the style guide. Notable changes in the Rust 2024 style edition
+include:
+
+- Miscellaneous `rustfmt` bugfixes.
+
+## Rust 2015/2018/2021 style edition
+
+The archived version of the style guide at
+<https://github.com/rust-lang/rust/tree/37343f4a4d4ed7ad0891cb79e8eb25acf43fb821/src/doc/style-guide/src>
+describes the style edition corresponding to Rust 2015, Rust 2018, and Rust
+2021.
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index f0c2a189f12e7..32c604f9f3e10 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -1,6 +1,6 @@
-## Expressions
+# Expressions
 
-### Blocks
+## Blocks
 
 A block expression must have a newline after the initial `{` and before the
 terminal `}`, unless it qualifies to be written as a single line based on
@@ -63,10 +63,10 @@ Write an empty block as `{}`.
 
 Write a block on a single line if:
 
-* it is either used in expression position (not statement position) or is an
+- it is either used in expression position (not statement position) or is an
   unsafe block in statement position,
-* it contains a single-line expression and no statements, and
-* it contains no comments
+- it contains a single-line expression and no statements, and
+- it contains no comments
 
 For a single-line block, put spaces after the opening brace and before the
 closing brace.
@@ -116,8 +116,7 @@ fn main() {
 }
 ```
 
-
-### Closures
+## Closures
 
 Don't put any extra spaces before the first `|` (unless the closure is prefixed
 by a keyword such as `move`); put a space between the second `|` and the
@@ -155,8 +154,7 @@ move |arg1: i32, arg2: i32| -> i32 {
 }
 ```
 
-
-### Struct literals
+## Struct literals
 
 If a struct literal is *small*, format it on a single line, and do not use a
 trailing comma. If not, split it across multiple lines, with each field on its
@@ -185,8 +183,7 @@ let f = Foo {
 };
 ```
 
-
-### Tuple literals
+## Tuple literals
 
 Use a single-line form where possible. Do not put spaces between the opening
 parenthesis and the first element, or between the last element and the closing
@@ -205,8 +202,7 @@ let x = (
 );
 ```
 
-
-### Tuple struct literals
+## Tuple struct literals
 
 Do not put space between the identifier and the opening parenthesis. Otherwise,
 follow the rules for tuple literals:
@@ -220,8 +216,7 @@ let x = Foo(
 );
 ```
 
-
-### Enum literals
+## Enum literals
 
 Follow the formatting rules for the various struct literals. Prefer using the
 name of the enum as a qualifying name, unless the enum is in the prelude:
@@ -235,8 +230,7 @@ Foo::Baz {
 Ok(an_expr)
 ```
 
-
-### Array literals
+## Array literals
 
 Write small array literals on a single line. Do not put spaces between the opening
 square bracket and the first element, or between the last element and the closing
@@ -276,8 +270,7 @@ fn main() {
 }
 ```
 
-
-### Array accesses, indexing, and slicing.
+## Array accesses, indexing, and slicing
 
 Don't put spaces around the square brackets. Avoid breaking lines if possible.
 Never break a line between the target expression and the opening square
@@ -300,13 +293,13 @@ fn main() {
 }
 ```
 
-### Unary operations
+## Unary operations
 
 Do not include a space between a unary op and its operand (i.e., `!x`, not
 `! x`). However, there must be a space after `&mut`. Avoid line-breaking
 between a unary operator and its operand.
 
-### Binary operations
+## Binary operations
 
 Do include spaces around binary ops (i.e., `x + 1`, not `x+1`) (including `=`
 and other assignment operators such as `+=` or `*=`).
@@ -335,7 +328,7 @@ foo_bar
 Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather
 than at other binary operators.
 
-### Control flow
+## Control flow
 
 Do not include extraneous parentheses for `if` and `while` expressions.
 
@@ -354,7 +347,7 @@ if (true) {
 Do include extraneous parentheses if it makes an arithmetic or logic expression
 easier to understand (`(x * 15) + (y * 20)` is fine)
 
-### Function calls
+## Function calls
 
 Do not put a space between the function name, and the opening parenthesis.
 
@@ -364,7 +357,7 @@ Do put a space between an argument, and the comma which precedes it.
 
 Prefer not to break a line in the callee expression.
 
-#### Single-line calls
+### Single-line calls
 
 Do not put a space between the function name and open paren, between the open
 paren and the first argument, or between the last argument and the close paren.
@@ -375,7 +368,7 @@ Do not put a comma after the last argument.
 foo(x, y, z)
 ```
 
-#### Multi-line calls
+### Multi-line calls
 
 If the function call is not *small*, it would otherwise over-run the max width,
 or any argument or the callee is multi-line, then format the call across
@@ -390,8 +383,7 @@ a_function_call(
 )
 ```
 
-
-### Method calls
+## Method calls
 
 Follow the function rules for calling.
 
@@ -401,15 +393,14 @@ Do not put any spaces around the `.`.
 x.foo().bar().baz(x, y, z);
 ```
 
-
-### Macro uses
+## Macro uses
 
 If a macro can be parsed like other constructs, format it like those
 constructs. For example, a macro use `foo!(a, b, c)` can be parsed like a
 function call (ignoring the `!`), so format it using the rules for function
 calls.
 
-#### Special case macros
+### Special case macros
 
 For macros which take a format string, if all other arguments are *small*,
 format the arguments before the format string on a single line if they fit, and
@@ -430,8 +421,7 @@ assert_eq!(
 );
 ```
 
-
-### Casts (`as`)
+## Casts (`as`)
 
 Put spaces before and after `as`:
 
@@ -439,8 +429,7 @@ Put spaces before and after `as`:
 let cstr = "Hi\0" as *const str as *const [u8] as *const std::os::raw::c_char;
 ```
 
-
-### Chains of fields and method calls
+## Chains of fields and method calls
 
 A chain is a sequence of field accesses, method calls, and/or uses of the try
 operator `?`. E.g., `a.b.c().d` or `foo?.bar().baz?`.
@@ -478,7 +467,7 @@ foo(
     .qux();
 ```
 
-#### Multi-line elements
+### Multi-line elements
 
 If any element in a chain is formatted across multiple lines, put that element
 and any later elements on their own lines.
@@ -513,7 +502,7 @@ self.pre_comment.as_ref().map_or(
 )
 ```
 
-### Control flow expressions
+## Control flow expressions
 
 This section covers `if`, `if let`, `loop`, `while`, `while let`, and `for`
 expressions.
@@ -584,8 +573,7 @@ if !self.config.file_lines().intersects(
 }
 ```
 
-
-#### Single line `if else`
+### Single line `if else`
 
 Put an `if else` or `if let else` on a single line if it occurs in expression
 context (i.e., is not a standalone statement), it contains a single `else`
@@ -608,8 +596,7 @@ if x {
 }
 ```
 
-
-### Match
+## Match
 
 Prefer not to line-break inside the discriminant expression. Always break after
 the opening brace and before the closing brace. Block-indent the match arms
@@ -718,7 +705,7 @@ match foo {
 }
 ```
 
-#### Line-breaking
+### Line-breaking
 
 If using a block form on the right-hand side of a match arm makes it possible
 to avoid breaking on the left-hand side, do that:
@@ -812,8 +799,7 @@ small_no_tuple:
 
 E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not.
 
-
-### Combinable expressions
+## Combinable expressions
 
 Where a function call has a single argument, and that argument is formatted
 across multiple-lines, format the outer call as if it were a single-line call,
@@ -861,8 +847,7 @@ foo(first_arg, x, |param| {
 })
 ```
 
-
-### Ranges
+## Ranges
 
 Do not put spaces in ranges, e.g., `0..10`, `x..=y`, `..x.len()`, `foo..`.
 
@@ -879,8 +864,7 @@ For the sake of indicating precedence, if either bound is a compound
 expression, use parentheses around it, e.g., `..(x + 1)`, `(x.f)..(x.f.len())`,
 or `0..(x - 10)`.
 
-
-### Hexadecimal literals
+## Hexadecimal literals
 
 Hexadecimal literals may use upper- or lower-case letters, but they must not be
 mixed within the same literal. Projects should use the same case for all
diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md
index 6e5ea335e6ab2..a6d941f6d0454 100644
--- a/src/doc/style-guide/src/items.md
+++ b/src/doc/style-guide/src/items.md
@@ -1,4 +1,4 @@
-## Items
+# Items
 
 Items consist of the set of things permitted at the top level of a module.
 However, Rust also allows some items to appear within some other types of
@@ -16,7 +16,7 @@ names.
 Don't automatically move module declarations annotated with `#[macro_use]`,
 since that might change semantics.
 
-### Function definitions
+## Function definitions
 
 In Rust, people often find functions by searching for `fn [function-name]`, so
 the formatting of function definitions must enable this.
@@ -46,14 +46,13 @@ fn foo(
 
 Note the trailing comma on the last argument.
 
-
-### Tuples and tuple structs
+## Tuples and tuple structs
 
 Write the type list as you would a parameter list to a function.
 
 Build a tuple or tuple struct as you would call a function.
 
-#### Single-line
+### Single-line
 
 ```rust
 struct Bar(Type1, Type2);
@@ -62,7 +61,7 @@ let x = Bar(11, 22);
 let y = (11, 22, 33);
 ```
 
-### Enums
+## Enums
 
 In the declaration, put each variant on its own line, block indented.
 
@@ -96,8 +95,7 @@ multiple lines, use the multi-line formatting for all struct variants. However,
 such a situation might be an indication that you should factor out the fields
 of the variant into their own struct.
 
-
-### Structs and Unions
+## Structs and Unions
 
 Struct names follow on the same line as the `struct` keyword, with the opening
 brace on the same line when it fits within the right margin. All struct fields
@@ -138,8 +136,7 @@ union Foo {
 }
 ```
 
-
-### Tuple structs
+## Tuple structs
 
 Put the whole struct on one line if possible. Separate types within the
 parentheses using a comma and space. Don't use a trailing comma for a
@@ -165,8 +162,7 @@ pub struct Foo(
 );
 ```
 
-
-### Traits
+## Traits
 
 Use block-indent for trait items. If there are no items, format the trait (including its `{}`)
 on a single line. Otherwise, break after the opening brace and before
@@ -204,8 +200,7 @@ pub trait IndexRanges:
 }
 ```
 
-
-### Impls
+## Impls
 
 Use block-indent for impl items. If there are no items, format the impl
 (including its `{}`) on a single line. Otherwise, break after the opening brace
@@ -231,15 +226,13 @@ impl Bar
 }
 ```
 
-
-### Extern crate
+## Extern crate
 
 `extern crate foo;`
 
 Use spaces around keywords, no spaces around the semicolon.
 
-
-### Modules
+## Modules
 
 ```rust
 mod foo {
@@ -253,7 +246,7 @@ mod foo;
 Use spaces around keywords and before the opening brace, no spaces around the
 semicolon.
 
-### macro\_rules!
+## `macro_rules!`
 
 Use `{}` for the full definition of the macro.
 
@@ -262,8 +255,7 @@ macro_rules! foo {
 }
 ```
 
-
-### Generics
+## Generics
 
 Prefer to put a generics clause on one line. Break other parts of an item
 declaration rather than line-breaking a generics clause. If a generics clause is
@@ -299,8 +291,7 @@ If an associated type is bound in a generic type, put spaces around the `=`:
 
 Prefer to use single-letter names for generic parameters.
 
-
-### `where` clauses
+## `where` clauses
 
 These rules apply for `where` clauses on any item.
 
@@ -373,7 +364,7 @@ where
         + Index<RangeFull>,
 ```
 
-### Type aliases
+## Type aliases
 
 Keep type aliases on one line when they fit. If necessary to break the line, do
 so after the `=`, and block-indent the right-hand side:
@@ -398,8 +389,7 @@ where
 = AnEvenLongerType<T, U, Foo<T>>;
 ```
 
-
-### Associated types
+## Associated types
 
 Format associated types like type aliases. Where an associated type has a
 bound, put a space after the colon but not before:
@@ -408,15 +398,13 @@ bound, put a space after the colon but not before:
 pub type Foo: Bar;
 ```
 
-
-### extern items
+## extern items
 
 When writing extern items (such as `extern "C" fn`), always specify the ABI.
 For example, write `extern "C" fn foo ...`, not `extern fn foo ...`, or
 `extern "C" { ... }`.
 
-
-### Imports (`use` statements)
+## Imports (`use` statements)
 
 Format imports on one line where possible. Don't put spaces around braces.
 
@@ -426,8 +414,7 @@ use a::b::d::*;
 use a::b::{foo, bar, baz};
 ```
 
-
-#### Large list imports
+### Large list imports
 
 Prefer to use multiple imports rather than a multi-line import. However, tools
 should not split imports by default.
@@ -437,7 +424,6 @@ does not fit within the max width, or because of the rules for nested imports
 below), then break after the opening brace and before the closing brace, use a
 trailing comma, and block indent the names.
 
-
 ```rust
 // Prefer
 foo::{long, list, of, imports};
@@ -450,8 +436,7 @@ foo::{
 };
 ```
 
-
-#### Ordering of imports
+### Ordering of imports
 
 A *group* of imports is a set of imports on the same or sequential lines. One or
 more blank lines or other items (e.g., a function) separate groups of imports.
@@ -459,7 +444,6 @@ more blank lines or other items (e.g., a function) separate groups of imports.
 Within a group of imports, imports must be sorted ASCIIbetically (uppercase
 before lowercase). Groups of imports must not be merged or re-ordered.
 
-
 E.g., input:
 
 ```rust
@@ -483,27 +467,25 @@ use b;
 Because of `macro_use`, attributes must also start a new group and prevent
 re-ordering.
 
-#### Ordering list import
+### Ordering list import
 
 Names in a list import must be sorted ASCIIbetically, but with `self` and
 `super` first, and groups and glob imports last. This applies recursively. For
 example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g.,
 `use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`.
 
-
-#### Normalisation
+### Normalisation
 
 Tools must make the following normalisations, recursively:
 
-* `use a::self;` -> `use a;`
-* `use a::{};` -> (nothing)
-* `use a::{b};` -> `use a::b;`
+- `use a::self;` -> `use a;`
+- `use a::{};` -> (nothing)
+- `use a::{b};` -> `use a::b;`
 
 Tools must not otherwise merge or un-merge import lists or adjust glob imports
 (without an explicit option).
 
-
-#### Nested imports
+### Nested imports
 
 If there are any nested imports in a list import, then use the multi-line form,
 even if the import fits on one line. Each nested import must be on its own line,
@@ -519,8 +501,7 @@ use a::b::{
 };
 ```
 
-
-#### Merging/un-merging imports
+### Merging/un-merging imports
 
 An example:
 
diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md
index 031811b0e6ff8..66e7fa3c9f89c 100644
--- a/src/doc/style-guide/src/nightly.md
+++ b/src/doc/style-guide/src/nightly.md
@@ -1,3 +1,5 @@
+# Nightly
+
 This chapter documents style and formatting for nightly-only syntax. The rest of the style guide documents style for stable Rust syntax; nightly syntax only appears in this chapter. Each section here includes the name of the feature gate, so that searches (e.g. `git grep`) for a nightly feature in the Rust repository also turn up the style guide section.
 
 Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization.
diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md
index d548693e39ed0..ce57c649a2d0b 100644
--- a/src/doc/style-guide/src/principles.md
+++ b/src/doc/style-guide/src/principles.md
@@ -3,27 +3,27 @@
 When deciding on style guidelines, the style team follows these guiding
 principles (in rough priority order):
 
-* readability
-    - scan-ability
-    - avoiding misleading formatting
-    - accessibility - readable and editable by users using the widest
-      variety of hardware, including non-visual accessibility interfaces
-    - readability of code in contexts without syntax highlighting or IDE
-      assistance, such as rustc error messages, diffs, grep, and other
-      plain-text contexts
+- readability
+  - scan-ability
+  - avoiding misleading formatting
+  - accessibility - readable and editable by users using the widest
+    variety of hardware, including non-visual accessibility interfaces
+  - readability of code in contexts without syntax highlighting or IDE
+    assistance, such as rustc error messages, diffs, grep, and other
+    plain-text contexts
 
-* aesthetics
-    - sense of 'beauty'
-    - consistent with other languages/tools
+- aesthetics
+  - sense of 'beauty'
+  - consistent with other languages/tools
 
-* specifics
-    - compatibility with version control practices - preserving diffs,
-      merge-friendliness, etc.
-    - preventing rightward drift
-    - minimising vertical space
+- specifics
+  - compatibility with version control practices - preserving diffs,
+    merge-friendliness, etc.
+  - preventing rightward drift
+  - minimising vertical space
 
-* application
-    - ease of manual application
-    - ease of implementation (in `rustfmt`, and in other tools/editors/code generators)
-    - internal consistency
-    - simplicity of formatting rules
+- application
+  - ease of manual application
+  - ease of implementation (in `rustfmt`, and in other tools/editors/code generators)
+  - internal consistency
+  - simplicity of formatting rules
diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md
index 8c8f893fbe904..6f322b3d65b54 100644
--- a/src/doc/style-guide/src/statements.md
+++ b/src/doc/style-guide/src/statements.md
@@ -1,6 +1,6 @@
-## Statements
+# Statements
 
-### Let statements
+## Let statements
 
 Put a space after the `:` and on both sides of the `=` (if they are present).
 Don't put a space before the semicolon.
@@ -28,7 +28,6 @@ use block indentation. If the type requires multiple lines, even after
 line-breaking after the `:`, then place the first line on the same line as the
 `:`, subject to the [combining rules](expressions.html#combinable-expressions).
 
-
 ```rust
 let pattern:
     Type =
@@ -101,7 +100,7 @@ let Foo {
 );
 ```
 
-#### else blocks (let-else statements)
+### else blocks (let-else statements)
 
 A let statement can contain an `else` component, making it a let-else statement.
 In this case, always apply the same formatting rules to the components preceding
@@ -231,7 +230,7 @@ fn main() {
 }
 ```
 
-### Macros in statement position
+## Macros in statement position
 
 For a macro use in statement position, use parentheses or square brackets as
 delimiters, and terminate it with a semicolon. Do not put spaces around the
@@ -242,8 +241,7 @@ name, `!`, the delimiters, or the `;`.
 a_macro!(...);
 ```
 
-
-### Expressions in statement position
+## Expressions in statement position
 
 Do not put space between the expression and the semicolon.
 
diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md
index 15b001d4f2ea5..b7921c8914e45 100644
--- a/src/doc/style-guide/src/types.md
+++ b/src/doc/style-guide/src/types.md
@@ -1,23 +1,22 @@
-## Types and Bounds
-
-### Single line formatting
-
-* `[T]` no spaces
-* `[T; expr]`, e.g., `[u32; 42]`, `[Vec<Foo>; 10 * 2 + foo()]` (space after colon, no spaces around square brackets)
-* `*const T`, `*mut T` (no space after `*`, space before type)
-* `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words)
-* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets)
-* `!` gets treated like any other type name, `Name`
-* `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple)
-* `<Baz<T> as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`)
-* `Foo::Bar<T, U, V>` (spaces after commas, no trailing comma, no spaces around angle brackets)
-* `T + T + T` (single spaces between types, and `+`).
-* `impl T + T + T` (single spaces between keyword, types, and `+`).
+# Types and Bounds
+
+## Single line formatting
+
+- `[T]` no spaces
+- `[T; expr]`, e.g., `[u32; 42]`, `[Vec<Foo>; 10 * 2 + foo()]` (space after colon, no spaces around square brackets)
+- `*const T`, `*mut T` (no space after `*`, space before type)
+- `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words)
+- `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets)
+- `!` gets treated like any other type name, `Name`
+- `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple)
+- `<Baz<T> as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`)
+- `Foo::Bar<T, U, V>` (spaces after commas, no trailing comma, no spaces around angle brackets)
+- `T + T + T` (single spaces between types, and `+`).
+- `impl T + T + T` (single spaces between keyword, types, and `+`).
 
 Do not put space around parentheses used in types, e.g., `(Foo)`
 
-
-### Line breaks
+## Line breaks
 
 Avoid breaking lines in types where possible. Prefer breaking at outermost scope, e.g., prefer
 
diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs
index 66876e02c1914..f20b7a2b4d729 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/tools/build_helper/src/git.rs
@@ -78,13 +78,22 @@ pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result<bool, String> {
 /// We will then fall back to origin/master in the hope that at least this exists.
 pub fn updated_master_branch(git_dir: Option<&Path>) -> Result<String, String> {
     let upstream_remote = get_rust_lang_rust_remote(git_dir)?;
-    let upstream_master = format!("{upstream_remote}/master");
-    if rev_exists(&upstream_master, git_dir)? {
-        return Ok(upstream_master);
+    for upstream_master in [format!("{upstream_remote}/master"), format!("origin/master")] {
+        if rev_exists(&upstream_master, git_dir)? {
+            return Ok(upstream_master);
+        }
     }
 
-    // We could implement smarter logic here in the future.
-    Ok("origin/master".into())
+    Err(format!("Cannot find any suitable upstream master branch"))
+}
+
+pub fn get_git_merge_base(git_dir: Option<&Path>) -> Result<String, String> {
+    let updated_master = updated_master_branch(git_dir)?;
+    let mut git = Command::new("git");
+    if let Some(git_dir) = git_dir {
+        git.current_dir(git_dir);
+    }
+    Ok(output_result(git.arg("merge-base").arg(&updated_master).arg("HEAD"))?.trim().to_owned())
 }
 
 /// Returns the files that have been modified in the current branch compared to the master branch.
@@ -94,20 +103,13 @@ pub fn get_git_modified_files(
     git_dir: Option<&Path>,
     extensions: &Vec<&str>,
 ) -> Result<Option<Vec<String>>, String> {
-    let Ok(updated_master) = updated_master_branch(git_dir) else {
-        return Ok(None);
-    };
-
-    let git = || {
-        let mut git = Command::new("git");
-        if let Some(git_dir) = git_dir {
-            git.current_dir(git_dir);
-        }
-        git
-    };
+    let merge_base = get_git_merge_base(git_dir)?;
 
-    let merge_base = output_result(git().arg("merge-base").arg(&updated_master).arg("HEAD"))?;
-    let files = output_result(git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))?
+    let mut git = Command::new("git");
+    if let Some(git_dir) = git_dir {
+        git.current_dir(git_dir);
+    }
+    let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))?
         .lines()
         .map(|s| s.trim().to_owned())
         .filter(|f| {