diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 358d412a4d8e2..213e8db66a056 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1317,10 +1317,14 @@ declare_lint! {
     ///
     /// ### Explanation
     ///
-    /// A bare `pub` visibility may be misleading if the item is not actually
-    /// publicly exported from the crate. The `pub(crate)` visibility is
-    /// recommended to be used instead, which more clearly expresses the intent
-    /// that the item is only visible within its own crate.
+    /// The `pub` keyword both expresses an intent for an item to be publicly available, and also
+    /// signals to the compiler to make the item publicly accessible. The intent can only be
+    /// satisfied, however, if all items which contain this item are *also* publicly accessible.
+    /// Thus, this lint serves to identify situations where the intent does not match the reality.
+    ///
+    /// If you wish the item to be accessible elsewhere within the crate, but not outside it, the
+    /// `pub(crate)` visibility is recommended to be used instead. This more clearly expresses the
+    /// intent that the item is only visible within its own crate.
     ///
     /// This lint is "allow" by default because it will trigger for a large
     /// amount existing Rust code, and has some false-positives. Eventually it
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index f31b343c94704..1511e25523559 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -291,10 +291,12 @@ impl<'tcx> CodegenUnit<'tcx> {
         self.primary = true;
     }
 
+    /// The order of these items is non-determinstic.
     pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
         &self.items
     }
 
+    /// The order of these items is non-determinstic.
     pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
         &mut self.items
     }
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index ecc50c3f664fd..89dadc782f2da 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,4 +1,5 @@
 #![feature(array_windows)]
+#![feature(is_sorted)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 0bacb58383dc0..015361f8ad5b7 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -126,11 +126,14 @@ struct PartitioningCx<'a, 'tcx> {
 }
 
 struct PlacedRootMonoItems<'tcx> {
+    /// The codegen units, sorted by name to make things deterministic.
     codegen_units: Vec<CodegenUnit<'tcx>>,
+
     roots: FxHashSet<MonoItem<'tcx>>,
     internalization_candidates: FxHashSet<MonoItem<'tcx>>,
 }
 
+// The output CGUs are sorted by name.
 fn partition<'tcx, I>(
     tcx: TyCtxt<'tcx>,
     mono_items: &mut I,
@@ -143,6 +146,7 @@ where
     let _prof_timer = tcx.prof.generic_activity("cgu_partitioning");
 
     let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map };
+
     // In the first step, we place all regular monomorphizations into their
     // respective 'home' codegen unit. Regular monomorphizations are all
     // functions and statics defined in the local crate.
@@ -225,8 +229,8 @@ where
         dead_code_cgu.make_code_coverage_dead_code_cgu();
     }
 
-    // Finally, sort by codegen unit name, so that we get deterministic results.
-    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
+    // Ensure CGUs are sorted by name, so that we get deterministic results.
+    assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str()))));
 
     debug_dump(tcx, "FINAL", &codegen_units);
 
@@ -301,27 +305,22 @@ where
         codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
     }
 
-    let codegen_units = codegen_units.into_values().collect();
+    let mut codegen_units: Vec<_> = codegen_units.into_values().collect();
+    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
+
     PlacedRootMonoItems { codegen_units, roots, internalization_candidates }
 }
 
+// This function requires the CGUs to be sorted by name on input, and ensures
+// they are sorted by name on return, for deterministic behaviour.
 fn merge_codegen_units<'tcx>(
     cx: &PartitioningCx<'_, 'tcx>,
     codegen_units: &mut Vec<CodegenUnit<'tcx>>,
 ) {
     assert!(cx.target_cgu_count >= 1);
 
-    // Note that at this point in time the `codegen_units` here may not be
-    // in a deterministic order (but we know they're deterministically the
-    // same set). We want this merging to produce a deterministic ordering
-    // of codegen units from the input.
-    //
-    // Due to basically how we've implemented the merging below (merge the
-    // two smallest into each other) we're sure to start off with a
-    // deterministic order (sorted by name). This'll mean that if two cgus
-    // have the same size the stable sort below will keep everything nice
-    // and deterministic.
-    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
+    // A sorted order here ensures merging is deterministic.
+    assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str()))));
 
     // This map keeps track of what got merged into what.
     let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
@@ -400,6 +399,9 @@ fn merge_codegen_units<'tcx>(
             cgu.set_name(numbered_codegen_unit_name);
         }
     }
+
+    // A sorted order here ensures what follows can be deterministic.
+    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
 }
 
 /// For symbol internalization, we need to know whether a symbol/mono-item is
@@ -859,36 +861,46 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
         _ => Visibility::Hidden,
     }
 }
+
 fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<'tcx>]) {
     let dump = move || {
         use std::fmt::Write;
 
         let num_cgus = cgus.len();
-        let max = cgus.iter().map(|cgu| cgu.size_estimate()).max().unwrap();
-        let min = cgus.iter().map(|cgu| cgu.size_estimate()).min().unwrap();
-        let ratio = max as f64 / min as f64;
+        let num_items: usize = cgus.iter().map(|cgu| cgu.items().len()).sum();
+        let total_size: usize = cgus.iter().map(|cgu| cgu.size_estimate()).sum();
+        let max_size = cgus.iter().map(|cgu| cgu.size_estimate()).max().unwrap();
+        let min_size = cgus.iter().map(|cgu| cgu.size_estimate()).min().unwrap();
+        let max_min_size_ratio = max_size as f64 / min_size as f64;
 
         let s = &mut String::new();
         let _ = writeln!(
             s,
-            "{label} ({num_cgus} CodegenUnits, max={max}, min={min}, max/min={ratio:.1}):"
+            "{label} ({num_items} items, total_size={total_size}; {num_cgus} CGUs, \
+             max_size={max_size}, min_size={min_size}, max_size/min_size={max_min_size_ratio:.1}):"
         );
-        for cgu in cgus {
-            let _ =
-                writeln!(s, "CodegenUnit {} estimated size {}:", cgu.name(), cgu.size_estimate());
+        for (i, cgu) in cgus.iter().enumerate() {
+            let num_items = cgu.items().len();
+            let _ = writeln!(
+                s,
+                "- CGU[{i}] {} ({num_items} items, size={}):",
+                cgu.name(),
+                cgu.size_estimate()
+            );
 
-            for (mono_item, linkage) in cgu.items() {
-                let symbol_name = mono_item.symbol_name(tcx).name;
+            // The order of `cgu.items()` is non-deterministic; sort it by name
+            // to give deterministic output.
+            let mut items: Vec<_> = cgu.items().iter().collect();
+            items.sort_by_key(|(item, _)| item.symbol_name(tcx).name);
+            for (item, linkage) in items {
+                let symbol_name = item.symbol_name(tcx).name;
                 let symbol_hash_start = symbol_name.rfind('h');
                 let symbol_hash = symbol_hash_start.map_or("<no hash>", |i| &symbol_name[i..]);
 
+                let size = item.size_estimate(tcx);
                 let _ = with_no_trimmed_paths!(writeln!(
                     s,
-                    " - {} [{:?}] [{}] estimated size {}",
-                    mono_item,
-                    linkage,
-                    symbol_hash,
-                    mono_item.size_estimate(tcx)
+                    "  - {item} [{linkage:?}] [{symbol_hash}] (size={size})"
                 ));
             }
 
diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs
index 2e3e0859dc18e..3fcaaa508e3c8 100644
--- a/library/std/src/sys/windows/stdio.rs
+++ b/library/std/src/sys/windows/stdio.rs
@@ -11,6 +11,9 @@ use crate::sys::cvt;
 use crate::sys::handle::Handle;
 use core::str::utf8_char_width;
 
+#[cfg(test)]
+mod tests;
+
 // Don't cache handles but get them fresh for every read/write. This allows us to track changes to
 // the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490.
 pub struct Stdin {
@@ -383,6 +386,10 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
     debug_assert!(utf16.len() <= c::c_int::MAX as usize);
     debug_assert!(utf8.len() <= c::c_int::MAX as usize);
 
+    if utf16.is_empty() {
+        return Ok(0);
+    }
+
     let result = unsafe {
         c::WideCharToMultiByte(
             c::CP_UTF8,              // CodePage
diff --git a/library/std/src/sys/windows/stdio/tests.rs b/library/std/src/sys/windows/stdio/tests.rs
new file mode 100644
index 0000000000000..1e53e0bee6369
--- /dev/null
+++ b/library/std/src/sys/windows/stdio/tests.rs
@@ -0,0 +1,6 @@
+use super::utf16_to_utf8;
+
+#[test]
+fn zero_size_read() {
+    assert_eq!(utf16_to_utf8(&[], &mut []).unwrap(), 0);
+}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 6e573c2284e5c..eec8c4ad69f23 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1772,6 +1772,14 @@ impl Step for BookTest {
     ///
     /// This uses the `rustdoc` that sits next to `compiler`.
     fn run(self, builder: &Builder<'_>) {
+        let host = self.compiler.host;
+        let _guard = builder.msg(
+            Kind::Test,
+            self.compiler.stage,
+            &format!("book {}", self.name),
+            host,
+            host,
+        );
         // External docs are different from local because:
         // - Some books need pre-processing by mdbook before being tested.
         // - They need to save their state to toolstate.
@@ -1963,7 +1971,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
         }
     }
 
-    builder.info(&format!("doc tests for: {}", markdown.display()));
+    builder.verbose(&format!("doc tests for: {}", markdown.display()));
     let mut cmd = builder.rustdoc_cmd(compiler);
     builder.add_rust_test_threads(&mut cmd);
     // allow for unstable options such as new editions
diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh
index ff17931115cd0..0807e0492c113 100755
--- a/src/etc/pre-push.sh
+++ b/src/etc/pre-push.sh
@@ -14,4 +14,4 @@ ROOT_DIR="$(git rev-parse --show-toplevel)"
 echo "Running pre-push script $ROOT_DIR/x test tidy"
 
 cd "$ROOT_DIR"
-CARGOFLAGS="--locked" ./x test tidy
+./x test tidy --set build.locked-deps=true
diff --git a/tests/rustdoc-gui/theme-in-history.goml b/tests/rustdoc-gui/theme-in-history.goml
index 8fcd0ecd3094b..42c5b5e6e69e3 100644
--- a/tests/rustdoc-gui/theme-in-history.goml
+++ b/tests/rustdoc-gui/theme-in-history.goml
@@ -7,7 +7,7 @@ set-local-storage: {
 }
 // We reload the page so the local storage settings are being used.
 reload:
-assert-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+assert-css: ("body", { "background-color": "#353535" })
 assert-local-storage: { "rustdoc-theme": "dark" }
 
 // Now we go to the settings page.
@@ -15,7 +15,7 @@ go-to: "file://" + |DOC_PATH| + "/settings.html"
 wait-for: "#settings"
 // We change the theme to "light".
 click: "#theme-light"
-wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+wait-for-css: ("body", { "background-color": "white" })
 assert-local-storage: { "rustdoc-theme": "light" }
 
 // We go back in history.
@@ -23,5 +23,5 @@ history-go-back:
 // Confirm that we're not on the settings page.
 assert-false: "#settings"
 // Check that the current theme is still "light".
-assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+assert-css: ("body", { "background-color": "white" })
 assert-local-storage: { "rustdoc-theme": "light" }
diff --git a/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs b/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs
new file mode 100644
index 0000000000000..5661db4a2530d
--- /dev/null
+++ b/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(inline_const)]
+
+fn main() {
+    let _my_usize = const {
+        let a = 10_usize;
+        let b: &'_ usize = &a;
+        *b
+    };
+}
diff --git a/triagebot.toml b/triagebot.toml
index c160c83cc9590..b1f4e9c77fbd5 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -387,6 +387,10 @@ cc = [
 message = "Some changes occurred in HTML/CSS themes."
 cc = ["@GuillaumeGomez"]
 
+[mentions."tests/rustdoc-gui/"]
+message = "Some changes occurred in GUI tests."
+cc = ["@GuillaumeGomez"]
+
 [mentions."src/librustdoc/html/static/css/themes/ayu.css"]
 message = "A change occurred in the Ayu theme."
 cc = ["@Cldfire"]