diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index 56f288ff051c2..aed36b12f3a22 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -509,44 +509,23 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             }
 
             AngleBrackets::Available => {
-                // angle brackets exist, so we insert missing arguments after the existing args
-
-                assert!(!self.gen_args.args.is_empty());
-
-                if self.num_provided_lifetime_args() > 0 {
-                    let last_lt_arg_span = self.gen_args.args
-                        [self.num_provided_lifetime_args() - 1]
-                        .span()
-                        .shrink_to_hi();
-                    let source_map = self.tcx.sess.source_map();
-
-                    if let Ok(last_gen_arg) = source_map.span_to_snippet(last_lt_arg_span) {
-                        let sugg = format!("{}, {}", last_gen_arg, suggested_args);
-
-                        err.span_suggestion_verbose(
-                            last_lt_arg_span,
-                            &msg,
-                            sugg,
-                            Applicability::HasPlaceholders,
-                        );
-                    }
+                let (sugg_span, is_first) = if self.num_provided_lifetime_args() == 0 {
+                    (self.gen_args.span().unwrap().shrink_to_lo(), true)
                 } else {
-                    // Non-lifetime arguments included in `gen_args` -> insert missing lifetimes before
-                    // existing arguments
-                    let first_arg_span = self.gen_args.args[0].span().shrink_to_lo();
-                    let source_map = self.tcx.sess.source_map();
-
-                    if let Ok(first_gen_arg) = source_map.span_to_snippet(first_arg_span) {
-                        let sugg = format!("{}, {}", suggested_args, first_gen_arg);
-
-                        err.span_suggestion_verbose(
-                            first_arg_span,
-                            &msg,
-                            sugg,
-                            Applicability::HasPlaceholders,
-                        );
-                    }
-                }
+                    let last_lt = &self.gen_args.args[self.num_provided_lifetime_args() - 1];
+                    (last_lt.span().shrink_to_hi(), false)
+                };
+                let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
+                let has_bindings = !self.gen_args.bindings.is_empty();
+
+                let sugg_prefix = if is_first { "" } else { ", " };
+                let sugg_suffix =
+                    if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" };
+
+                let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix);
+                debug!("sugg: {:?}", sugg);
+
+                err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders);
             }
             AngleBrackets::Implied => {
                 // We never encounter missing lifetimes in situations in which lifetimes are elided
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 302f12af6a0fe..2a4ef553be399 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -10,7 +10,6 @@ use crate::error::Error;
 use crate::fmt::{self, Write};
 use crate::io;
 use crate::mem;
-use crate::memchr;
 use crate::num::NonZeroU8;
 use crate::ops;
 use crate::os::raw::c_char;
@@ -20,6 +19,7 @@ use crate::slice;
 use crate::str::{self, Utf8Error};
 use crate::sync::Arc;
 use crate::sys;
+use crate::sys_common::memchr;
 
 /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the
 /// middle.
diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs
index d0c859d2e0c87..0175d2693e894 100644
--- a/library/std/src/io/buffered/linewritershim.rs
+++ b/library/std/src/io/buffered/linewritershim.rs
@@ -1,5 +1,5 @@
 use crate::io::{self, BufWriter, IoSlice, Write};
-use crate::memchr;
+use crate::sys_common::memchr;
 
 /// Private helper struct for implementing the line-buffered writing logic.
 /// This shim temporarily wraps a BufWriter, and uses its internals to
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index e18402f8dec1c..a8f3412c61116 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -253,12 +253,12 @@ mod tests;
 
 use crate::cmp;
 use crate::fmt;
-use crate::memchr;
 use crate::ops::{Deref, DerefMut};
 use crate::ptr;
 use crate::slice;
 use crate::str;
 use crate::sys;
+use crate::sys_common::memchr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::buffered::IntoInnerError;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 6d11698d26822..442b5628d1dc0 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -530,7 +530,6 @@ mod sys;
 pub mod alloc;
 
 // Private support modules
-mod memchr;
 mod panicking;
 
 // The runtime entry point and a few unstable public functions used by the
diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs
index 81cd68a74e665..40bd393098f57 100644
--- a/library/std/src/sys/hermit/os.rs
+++ b/library/std/src/sys/hermit/os.rs
@@ -4,11 +4,11 @@ use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::memchr;
 use crate::path::{self, PathBuf};
 use crate::str;
 use crate::sync::Mutex;
 use crate::sys::hermit::abi;
+use crate::sys::memchr;
 use crate::sys::unsupported;
 use crate::sys_common::os_str_bytes::*;
 use crate::vec;
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index 51c3e5d175cca..bbc4691d963c6 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -13,13 +13,13 @@ use crate::fmt;
 use crate::io;
 use crate::iter;
 use crate::mem;
-use crate::memchr;
 use crate::path::{self, PathBuf};
 use crate::ptr;
 use crate::slice;
 use crate::str;
 use crate::sys::cvt;
 use crate::sys::fd;
+use crate::sys::memchr;
 use crate::sys::rwlock::{RWLockReadGuard, StaticRWLock};
 use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
 use crate::vec;
diff --git a/library/std/src/memchr.rs b/library/std/src/sys_common/memchr.rs
similarity index 92%
rename from library/std/src/memchr.rs
rename to library/std/src/sys_common/memchr.rs
index 86a08f75a8d48..b219e87891264 100644
--- a/library/std/src/memchr.rs
+++ b/library/std/src/sys_common/memchr.rs
@@ -1,6 +1,8 @@
 // Original implementation taken from rust-memchr.
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
+use crate::sys::memchr as sys;
+
 #[cfg(test)]
 mod tests;
 
@@ -25,7 +27,7 @@ mod tests;
 /// ```
 #[inline]
 pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
-    crate::sys::memchr::memchr(needle, haystack)
+    sys::memchr(needle, haystack)
 }
 
 /// A safe interface to `memrchr`.
@@ -45,5 +47,5 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
 /// ```
 #[inline]
 pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
-    crate::sys::memchr::memrchr(needle, haystack)
+    sys::memrchr(needle, haystack)
 }
diff --git a/library/std/src/memchr/tests.rs b/library/std/src/sys_common/memchr/tests.rs
similarity index 100%
rename from library/std/src/memchr/tests.rs
rename to library/std/src/sys_common/memchr/tests.rs
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 4ef0e72adf020..1a9caa22c9243 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -25,6 +25,7 @@ pub mod bytestring;
 pub mod condvar;
 pub mod fs;
 pub mod io;
+pub mod memchr;
 pub mod mutex;
 // `doc` is required because `sys/mod.rs` imports `unix/ext/mod.rs` on Windows
 // when generating documentation.
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index dd8c6023a44cb..98b5bfd3b980a 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -52,7 +52,10 @@ impl Step for ToolBuild {
         let is_optional_tool = self.is_optional_tool;
 
         match self.mode {
-            Mode::ToolRustc => builder.ensure(compile::Rustc { compiler, target }),
+            Mode::ToolRustc => {
+                builder.ensure(compile::Std { compiler, target: compiler.host });
+                builder.ensure(compile::Rustc { compiler, target });
+            }
             Mode::ToolStd => builder.ensure(compile::Std { compiler, target }),
             Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs
             _ => panic!("unexpected Mode for tool build"),
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 8204949267250..1ed94ec109c18 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -161,7 +161,7 @@ function hideThemeButtonState() {
         outputElement: function() {
             return document.getElementById("search");
         },
-        title: null,
+        title: document.title,
         titleBeforeSearch: document.title,
         timeout: null,
         // On the search screen, so you remain on the last tab you opened.
diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml
index 303dd000ba391..ec034f52c972c 100644
--- a/src/test/rustdoc-gui/escape-key.goml
+++ b/src/test/rustdoc-gui/escape-key.goml
@@ -22,6 +22,13 @@ assert: ("#help", "class", "hidden")
 assert: ("#search", "class", "content")
 assert: ("#main", "class", "content hidden")
 
-// FIXME: Once https://github.com/rust-lang/rust/pull/84462 is merged, add check to ensure
-// that Escape hides the search results when a result is focused.
-// press-key: "ArrowDown"
+// Check that Escape hides the search results when a search result is focused.
+focus: ".search-input"
+assert: ".search-input:focus"
+press-key: "ArrowDown"
+assert-false: ".search-input:focus"
+assert: "#results a:focus"
+press-key: "Escape"
+assert: ("#help", "class", "hidden")
+assert: ("#search", "class", "content hidden")
+assert: ("#main", "class", "content")
diff --git a/src/test/ui/suggestions/issue-85347.rs b/src/test/ui/suggestions/issue-85347.rs
new file mode 100644
index 0000000000000..f08e38689d6af
--- /dev/null
+++ b/src/test/ui/suggestions/issue-85347.rs
@@ -0,0 +1,10 @@
+#![allow(incomplete_features)]
+#![feature(generic_associated_types)]
+use std::ops::Deref;
+trait Foo {
+    type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
+    //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+    //~| HELP add missing
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-85347.stderr b/src/test/ui/suggestions/issue-85347.stderr
new file mode 100644
index 0000000000000..60594baa29cb6
--- /dev/null
+++ b/src/test/ui/suggestions/issue-85347.stderr
@@ -0,0 +1,19 @@
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+  --> $DIR/issue-85347.rs:5:42
+   |
+LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
+   |                                          ^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-85347.rs:5:10
+   |
+LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
+   |          ^^^ --
+help: add missing lifetime argument
+   |
+LL |     type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
+   |                                              ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.