From 4dded23925994103e3e793d5edbe0d30222cdaa4 Mon Sep 17 00:00:00 2001
From: Ibraheem Ahmed <ibraheem@ibraheem.ca>
Date: Mon, 28 Feb 2022 19:59:21 -0500
Subject: [PATCH 01/19] add `special_module_name` lint

---
 compiler/rustc_lint/src/builtin.rs            | 74 +++++++++++++++++++
 compiler/rustc_lint/src/lib.rs                |  1 +
 src/test/ui/modules/dummy.rs                  |  0
 src/test/ui/modules/special_module_name.rs    |  8 ++
 .../ui/modules/special_module_name.stderr     | 37 ++++++++++
 .../ui/modules/special_module_name_ignore.rs  |  9 +++
 6 files changed, 129 insertions(+)
 create mode 100644 src/test/ui/modules/dummy.rs
 create mode 100644 src/test/ui/modules/special_module_name.rs
 create mode 100644 src/test/ui/modules/special_module_name.stderr
 create mode 100644 src/test/ui/modules/special_module_name_ignore.rs

diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 30b5f9b34d099..961e1e9507b97 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -3248,3 +3248,77 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
         }
     }
 }
+
+declare_lint! {
+    /// The `special_module_name` lint detects module
+    /// declarations for files that have a special meaning.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// mod lib;
+    ///
+    /// fn main() {
+    ///     lib::run();
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Cargo recognizes `lib.rs` and `main.rs` as the root of a
+    /// library or binary crate, so declaring them as modules
+    /// will lead to miscompilation of the crate unless configured
+    /// explicitly.
+    ///
+    /// To access a library from a binary target within the same crate,
+    /// use `your_crate_name::` as the path path instead of `lib::`:
+    ///
+    /// ```rust,compile_fail
+    /// // bar/src/lib.rs
+    /// fn run() {
+    ///     // ...
+    /// }
+    ///
+    /// // bar/src/main.rs
+    /// fn main() {
+    ///     bar::run();
+    /// }
+    /// ```
+    ///
+    /// Binary targets cannot be used as libraries and so declaring
+    /// one as a module is not allowed.
+    pub SPECIAL_MODULE_NAME,
+    Warn,
+    "module declarations for files with a special meaning",
+}
+
+declare_lint_pass!(SpecialModuleName => [SPECIAL_MODULE_NAME]);
+
+impl EarlyLintPass for SpecialModuleName {
+    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
+        for item in &krate.items {
+            if let ast::ItemKind::Mod(..) = item.kind {
+                if item.attrs.iter().any(|a| a.has_name(sym::path)) {
+                    continue;
+                }
+
+                match item.ident.name.as_str() {
+                    "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
+                        lint.build("found module declaration for lib.rs")
+                            .note("lib.rs is the root of this crate's library target")
+                            .help("to refer to it from other targets, use the library's name as the path")
+                            .emit()
+                    }),
+                    "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
+                        lint.build("found module declaration for main.rs")
+                            .note("a binary crate cannot be used as library")
+                            .emit()
+                    }),
+                    _ => continue
+                }
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 69863b5ff827f..107df79c3809b 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -129,6 +129,7 @@ macro_rules! early_lint_passes {
                 UnusedBraces: UnusedBraces,
                 UnusedImportBraces: UnusedImportBraces,
                 UnsafeCode: UnsafeCode,
+                SpecialModuleName: SpecialModuleName,
                 AnonymousParameters: AnonymousParameters,
                 EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
                 NonCamelCaseTypes: NonCamelCaseTypes,
diff --git a/src/test/ui/modules/dummy.rs b/src/test/ui/modules/dummy.rs
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/src/test/ui/modules/special_module_name.rs b/src/test/ui/modules/special_module_name.rs
new file mode 100644
index 0000000000000..15c59b2da828c
--- /dev/null
+++ b/src/test/ui/modules/special_module_name.rs
@@ -0,0 +1,8 @@
+mod lib;
+//~^ WARN found module declaration for lib.rs
+//~| ERROR file not found for module `lib`
+mod main;
+//~^ WARN found module declaration for main.rs
+//~| ERROR file not found for module `main`
+
+fn main() {}
diff --git a/src/test/ui/modules/special_module_name.stderr b/src/test/ui/modules/special_module_name.stderr
new file mode 100644
index 0000000000000..8b3da29386df2
--- /dev/null
+++ b/src/test/ui/modules/special_module_name.stderr
@@ -0,0 +1,37 @@
+error[E0583]: file not found for module `lib`
+  --> $DIR/special_module_name.rs:1:1
+   |
+LL | mod lib;
+   | ^^^^^^^^
+   |
+   = help: to create the module `lib`, create file "$DIR/lib.rs" or "$DIR/lib/mod.rs"
+
+error[E0583]: file not found for module `main`
+  --> $DIR/special_module_name.rs:4:1
+   |
+LL | mod main;
+   | ^^^^^^^^^
+   |
+   = help: to create the module `main`, create file "$DIR/main.rs" or "$DIR/main/mod.rs"
+
+warning: found module declaration for lib.rs
+  --> $DIR/special_module_name.rs:1:1
+   |
+LL | mod lib;
+   | ^^^^^^^^
+   |
+   = note: `#[warn(special_module_name)]` on by default
+   = note: lib.rs is the root of this crate's library target
+   = help: to refer to it from other targets, use the library's name as the path
+
+warning: found module declaration for main.rs
+  --> $DIR/special_module_name.rs:4:1
+   |
+LL | mod main;
+   | ^^^^^^^^^
+   |
+   = note: a binary crate cannot be used as library
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/modules/special_module_name_ignore.rs b/src/test/ui/modules/special_module_name_ignore.rs
new file mode 100644
index 0000000000000..cae06b49ee0b7
--- /dev/null
+++ b/src/test/ui/modules/special_module_name_ignore.rs
@@ -0,0 +1,9 @@
+// run-pass
+
+#[path = "dummy.rs"]
+mod lib;
+
+#[path = "dummy.rs"]
+mod main;
+
+fn main() {}

From c08f460beb86b60aab150f258d96bf99c6eae1b8 Mon Sep 17 00:00:00 2001
From: Ibraheem Ahmed <ibraheem@ibraheem.ca>
Date: Fri, 15 Apr 2022 16:21:21 -0400
Subject: [PATCH 02/19] tidy

---
 src/test/ui/modules/dummy.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/test/ui/modules/dummy.rs b/src/test/ui/modules/dummy.rs
index e69de29bb2d1d..831e38292a9ba 100644
--- a/src/test/ui/modules/dummy.rs
+++ b/src/test/ui/modules/dummy.rs
@@ -0,0 +1 @@
+pub struct Dummy;

From f479289e78bc60fbb2aaa3abb33f7726bb12ea89 Mon Sep 17 00:00:00 2001
From: Ibraheem Ahmed <ibraheem@ibraheem.ca>
Date: Sat, 4 Jun 2022 16:12:45 -0400
Subject: [PATCH 03/19] move dummy test module to auxiliary directory

---
 src/test/ui/modules/auxiliary/dummy_lib.rs        | 2 ++
 src/test/ui/modules/dummy.rs                      | 1 -
 src/test/ui/modules/special_module_name_ignore.rs | 4 ++--
 3 files changed, 4 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/modules/auxiliary/dummy_lib.rs
 delete mode 100644 src/test/ui/modules/dummy.rs

diff --git a/src/test/ui/modules/auxiliary/dummy_lib.rs b/src/test/ui/modules/auxiliary/dummy_lib.rs
new file mode 100644
index 0000000000000..ef805c1f02031
--- /dev/null
+++ b/src/test/ui/modules/auxiliary/dummy_lib.rs
@@ -0,0 +1,2 @@
+#[allow(dead_code)]
+pub struct Dummy;
diff --git a/src/test/ui/modules/dummy.rs b/src/test/ui/modules/dummy.rs
deleted file mode 100644
index 831e38292a9ba..0000000000000
--- a/src/test/ui/modules/dummy.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub struct Dummy;
diff --git a/src/test/ui/modules/special_module_name_ignore.rs b/src/test/ui/modules/special_module_name_ignore.rs
index cae06b49ee0b7..07cea9b2b05a1 100644
--- a/src/test/ui/modules/special_module_name_ignore.rs
+++ b/src/test/ui/modules/special_module_name_ignore.rs
@@ -1,9 +1,9 @@
 // run-pass
 
-#[path = "dummy.rs"]
+#[path = "auxiliary/dummy_lib.rs"]
 mod lib;
 
-#[path = "dummy.rs"]
+#[path = "auxiliary/dummy_lib.rs"]
 mod main;
 
 fn main() {}

From 4fdf43f23fbd4fb69960c9136dc796d8e64be785 Mon Sep 17 00:00:00 2001
From: Ibraheem Ahmed <ibraheem@ibraheem.ca>
Date: Thu, 21 Jul 2022 13:06:08 -0400
Subject: [PATCH 04/19] `special_module_name`: ignore inline modules

---
 compiler/rustc_lint/src/builtin.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 961e1e9507b97..e9841b7f07132 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -3299,7 +3299,11 @@ declare_lint_pass!(SpecialModuleName => [SPECIAL_MODULE_NAME]);
 impl EarlyLintPass for SpecialModuleName {
     fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
         for item in &krate.items {
-            if let ast::ItemKind::Mod(..) = item.kind {
+            if let ast::ItemKind::Mod(
+                _,
+                ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _),
+            ) = item.kind
+            {
                 if item.attrs.iter().any(|a| a.has_name(sym::path)) {
                     continue;
                 }

From b9c47f624e8baaccde5b8c022a9fd61d07bda106 Mon Sep 17 00:00:00 2001
From: Samyak Sarnayak <samyak201@gmail.com>
Date: Sun, 21 Aug 2022 23:21:58 +0530
Subject: [PATCH 05/19] Use getuid to check instead of USER env var in
 rustbuild

This makes it consistent with `x.py` as changed in #95671

Fixes #100459
---
 src/bootstrap/bootstrap.py |  2 ++
 src/bootstrap/lib.rs       | 13 +++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 9301c5a2ff300..03eec02a8bf01 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -793,6 +793,8 @@ def set_dist_environment(self, url):
 
     def check_vendored_status(self):
         """Check that vendoring is configured properly"""
+        # keep this consistent with the equivalent check in rustbuild:
+        # https://github.com/rust-lang/rust/blob/a8a33cf27166d3eabaffc58ed3799e054af3b0c6/src/bootstrap/lib.rs#L399-L405
         if 'SUDO_USER' in os.environ and not self.use_vendored_sources:
             if os.getuid() == 0:
                 self.use_vendored_sources = True
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index dcfa92d1004cd..74edbf3701ce7 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -396,13 +396,18 @@ impl Build {
         let src = config.src.clone();
         let out = config.out.clone();
 
+        #[cfg(unix)]
+        // keep this consistent with the equivalent check in x.py:
+        // https://github.com/rust-lang/rust/blob/a8a33cf27166d3eabaffc58ed3799e054af3b0c6/src/bootstrap/bootstrap.py#L796-L797
         let is_sudo = match env::var_os("SUDO_USER") {
-            Some(sudo_user) => match env::var_os("USER") {
-                Some(user) => user != sudo_user,
-                None => false,
-            },
+            Some(_sudo_user) => {
+                let uid = unsafe { libc::getuid() };
+                uid == 0
+            }
             None => false,
         };
+        #[cfg(not(unix))]
+        let is_sudo = false;
 
         let ignore_git = config.ignore_git;
         let rust_info = channel::GitInfo::new(ignore_git, &src);

From e136e02fd97ac5207f1a0d1edd276ef22a1d24c1 Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@google.com>
Date: Fri, 26 Aug 2022 19:24:41 -0700
Subject: [PATCH 06/19] bootstrap: Add llvm-has-rust-patches target option

This is so you can check out an upstream commit in src/llvm-project and
have everything just work.
---
 config.toml.example     |  4 ++++
 src/bootstrap/config.rs |  3 +++
 src/bootstrap/lib.rs    | 12 +++++++-----
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/config.toml.example b/config.toml.example
index b3284050f0530..28ccc2c8f14d1 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -666,6 +666,10 @@ changelog-seen = 2
 # target.
 #llvm-config = <none> (path)
 
+# Override detection of whether this is a Rust-patched LLVM. This would be used
+# in conjunction with either an llvm-config or build.submodules = false.
+#llvm-has-rust-patches = if llvm-config { false } else { true }
+
 # Normally the build system can find LLVM's FileCheck utility, but if
 # not, you can specify an explicit file name for it.
 #llvm-filecheck = "/path/to/llvm-version/bin/FileCheck"
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index ea0f78e2a6be9..f98f07b8eba2c 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -388,6 +388,7 @@ impl PartialEq<&str> for TargetSelection {
 pub struct Target {
     /// Some(path to llvm-config) if using an external LLVM.
     pub llvm_config: Option<PathBuf>,
+    pub llvm_has_rust_patches: Option<bool>,
     /// Some(path to FileCheck) if one was specified.
     pub llvm_filecheck: Option<PathBuf>,
     pub llvm_libunwind: Option<LlvmLibunwind>,
@@ -729,6 +730,7 @@ define_config! {
         default_linker: Option<PathBuf> = "default-linker",
         linker: Option<String> = "linker",
         llvm_config: Option<String> = "llvm-config",
+        llvm_has_rust_patches: Option<bool> = "llvm-has-rust-patches",
         llvm_filecheck: Option<String> = "llvm-filecheck",
         llvm_libunwind: Option<String> = "llvm-libunwind",
         android_ndk: Option<String> = "android-ndk",
@@ -1140,6 +1142,7 @@ impl Config {
                 if let Some(ref s) = cfg.llvm_config {
                     target.llvm_config = Some(config.src.join(s));
                 }
+                target.llvm_has_rust_patches = cfg.llvm_has_rust_patches;
                 if let Some(ref s) = cfg.llvm_filecheck {
                     target.llvm_filecheck = Some(config.src.join(s));
                 }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index cd421c249d8da..751692b46f391 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -112,6 +112,7 @@ use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::str;
 
+use config::Target;
 use filetime::FileTime;
 use once_cell::sync::OnceCell;
 
@@ -854,12 +855,13 @@ impl Build {
     ///
     /// If no custom `llvm-config` was specified then Rust's llvm will be used.
     fn is_rust_llvm(&self, target: TargetSelection) -> bool {
-        if self.config.llvm_from_ci && target == self.config.build {
-            return true;
-        }
-
         match self.config.target_config.get(&target) {
-            Some(ref c) => c.llvm_config.is_none(),
+            Some(Target { llvm_has_rust_patches: Some(patched), .. }) => *patched,
+            Some(Target { llvm_config, .. }) => {
+                // If the user set llvm-config we assume Rust is not patched,
+                // but first check to see if it was configured by llvm-from-ci.
+                (self.config.llvm_from_ci && target == self.config.build) || llvm_config.is_none()
+            }
             None => true,
         }
     }

From 73958fdf14d965eac2148991af99f0e0ad0c97ad Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@google.com>
Date: Fri, 26 Aug 2022 19:29:39 -0700
Subject: [PATCH 07/19] Ignore cargo target folder in src/bootstrap

Needed after changes in #97513.
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index a6625ac2ac4a1..79405e377756c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@ no_llvm_build
 /dist/
 /unicode-downloads
 /target
+/src/bootstrap/target
 /src/tools/x/target
 # Created by default with `src/ci/docker/run.sh`
 /obj/

From de6a3ec61a3d7af121bc4894f46516f6ee24932f Mon Sep 17 00:00:00 2001
From: yjhn <54238857+yjhn@users.noreply.github.com>
Date: Tue, 30 Aug 2022 12:29:18 +0300
Subject: [PATCH 08/19] Make docs formulation more consistent for NonZero{int}

Use third person, as it is used for other std documentation.
---
 library/core/src/num/nonzero.rs | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 6196c4da4e329..1cf306f2103b4 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -309,8 +309,8 @@ macro_rules! nonzero_unsigned_operations {
     ( $( $Ty: ident($Int: ident); )+ ) => {
         $(
             impl $Ty {
-                /// Add an unsigned integer to a non-zero value.
-                /// Check for overflow and return [`None`] on overflow
+                /// Adds an unsigned integer to a non-zero value.
+                /// Checks for overflow and returns [`None`] on overflow.
                 /// As a consequence, the result cannot wrap to zero.
                 ///
                 ///
@@ -346,7 +346,7 @@ macro_rules! nonzero_unsigned_operations {
                     }
                 }
 
-                /// Add an unsigned integer to a non-zero value.
+                /// Adds an unsigned integer to a non-zero value.
                 #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
                 ///
                 /// # Examples
@@ -377,7 +377,7 @@ macro_rules! nonzero_unsigned_operations {
                     unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
                 }
 
-                /// Add an unsigned integer to a non-zero value,
+                /// Adds an unsigned integer to a non-zero value,
                 /// assuming overflow cannot occur.
                 /// Overflow is unchecked, and it is undefined behaviour to overflow
                 /// *even if the result would wrap to a non-zero value*.
@@ -409,7 +409,7 @@ macro_rules! nonzero_unsigned_operations {
                 }
 
                 /// Returns the smallest power of two greater than or equal to n.
-                /// Check for overflow and return [`None`]
+                /// Checks for overflow and returns [`None`]
                 /// if the next power of two is greater than the type’s maximum value.
                 /// As a consequence, the result cannot wrap to zero.
                 ///
@@ -545,7 +545,7 @@ macro_rules! nonzero_signed_operations {
                 }
 
                 /// Checked absolute value.
-                /// Check for overflow and returns [`None`] if
+                /// Checks for overflow and returns [`None`] if
                 #[doc = concat!("`self == ", stringify!($Int), "::MIN`.")]
                 /// The result cannot be zero.
                 ///
@@ -740,8 +740,8 @@ macro_rules! nonzero_unsigned_signed_operations {
     ( $( $signedness:ident $Ty: ident($Int: ty); )+ ) => {
         $(
             impl $Ty {
-                /// Multiply two non-zero integers together.
-                /// Check for overflow and return [`None`] on overflow.
+                /// Multiplies two non-zero integers together.
+                /// Checks for overflow and returns [`None`] on overflow.
                 /// As a consequence, the result cannot wrap to zero.
                 ///
                 /// # Examples
@@ -777,7 +777,7 @@ macro_rules! nonzero_unsigned_signed_operations {
                     }
                 }
 
-                /// Multiply two non-zero integers together.
+                /// Multiplies two non-zero integers together.
                 #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
                 ///
                 /// # Examples
@@ -809,7 +809,7 @@ macro_rules! nonzero_unsigned_signed_operations {
                     unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
                 }
 
-                /// Multiply two non-zero integers together,
+                /// Multiplies two non-zero integers together,
                 /// assuming overflow cannot occur.
                 /// Overflow is unchecked, and it is undefined behaviour to overflow
                 /// *even if the result would wrap to a non-zero value*.
@@ -849,8 +849,8 @@ macro_rules! nonzero_unsigned_signed_operations {
                     unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
                 }
 
-                /// Raise non-zero value to an integer power.
-                /// Check for overflow and return [`None`] on overflow.
+                /// Raises non-zero value to an integer power.
+                /// Checks for overflow and returns [`None`] on overflow.
                 /// As a consequence, the result cannot wrap to zero.
                 ///
                 /// # Examples

From 8410df3791fdf7e0fee9c98df19bc02d0958aab9 Mon Sep 17 00:00:00 2001
From: est31 <MTest31@outlook.com>
Date: Tue, 30 Aug 2022 23:05:51 +0200
Subject: [PATCH 09/19] Also replace the version placeholder in rustc_attr

This fixes rustdoc not showing the current version as stabilization version
for recently stabilized lang features.
---
 compiler/rustc_attr/src/builtin.rs                | 12 ++++++++++++
 compiler/rustc_passes/src/lib_features.rs         |  2 +-
 src/tools/replace-version-placeholder/src/main.rs |  2 +-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 65edab78ce74e..12a539b5b55ac 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -15,6 +15,12 @@ use std::num::NonZeroU32;
 
 use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
 
+/// The version placeholder that recently stabilized features contain inside the
+/// `since` field of the `#[stable]` attribute.
+///
+/// For more, see https://github.com/rust-lang/rust/pull/100591
+pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
+
 pub fn is_builtin_attr(attr: &Attribute) -> bool {
     attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
 }
@@ -483,6 +489,12 @@ where
                         }
                     }
 
+                    if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
+                        let version = option_env!("CFG_VERSION").unwrap_or("<current>");
+                        let version = version.split(' ').next().unwrap();
+                        since = Some(Symbol::intern(&version));
+                    }
+
                     match (feature, since) {
                         (Some(feature), Some(since)) => {
                             let level = Stable { since, allowed_through_unstable_modules: false };
diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index 70b6bfd1e582d..5aac6943eef1e 100644
--- a/compiler/rustc_passes/src/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
@@ -5,6 +5,7 @@
 //! collect them instead.
 
 use rustc_ast::{Attribute, MetaItemKind};
+use rustc_attr::VERSION_PLACEHOLDER;
 use rustc_errors::struct_span_err;
 use rustc_hir::intravisit::Visitor;
 use rustc_middle::hir::nested_filter;
@@ -54,7 +55,6 @@ impl<'tcx> LibFeatureCollector<'tcx> {
                         }
                     }
                 }
-                const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
 
                 if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
                     let version = option_env!("CFG_VERSION").unwrap_or("<current>");
diff --git a/src/tools/replace-version-placeholder/src/main.rs b/src/tools/replace-version-placeholder/src/main.rs
index 146e53f2e9a0f..33b35d0541576 100644
--- a/src/tools/replace-version-placeholder/src/main.rs
+++ b/src/tools/replace-version-placeholder/src/main.rs
@@ -14,7 +14,7 @@ fn main() {
             walk::filter_dirs(path)
                 // We exempt these as they require the placeholder
                 // for their operation
-                || path.ends_with("compiler/rustc_passes/src/lib_features.rs")
+                || path.ends_with("compiler/rustc_attr/src/builtin.rs")
                 || path.ends_with("src/tools/tidy/src/features/version.rs")
                 || path.ends_with("src/tools/replace-version-placeholder")
         },

From 803e35abf7c2949fe04d1c403d69605f570d5637 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Wed, 31 Aug 2022 17:05:38 +0200
Subject: [PATCH 10/19] Remove unneeded extra whitespace before where clause

---
 src/librustdoc/html/format.rs     | 13 ++++---------
 src/librustdoc/html/render/mod.rs | 12 ++++++------
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index b023792e95a58..05d10f8137fe8 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -349,8 +349,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
         let where_preds = comma_sep(where_predicates, false);
         let clause = if f.alternate() {
             if ending == Ending::Newline {
-                // add a space so stripping <br> tags and breaking spaces still renders properly
-                format!(" where{where_preds}, ")
+                format!(" where{where_preds},")
             } else {
                 format!(" where{where_preds}")
             }
@@ -364,20 +363,16 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
 
             if ending == Ending::Newline {
                 let mut clause = "&nbsp;".repeat(indent.saturating_sub(1));
-                // add a space so stripping <br> tags and breaking spaces still renders properly
-                write!(
-                    clause,
-                    " <span class=\"where fmt-newline\">where{where_preds},&nbsp;</span>"
-                )?;
+                write!(clause, "<span class=\"where fmt-newline\">where{where_preds},</span>")?;
                 clause
             } else {
                 // insert a <br> tag after a single space but before multiple spaces at the start
                 if indent == 0 {
-                    format!(" <br><span class=\"where\">where{where_preds}</span>")
+                    format!("<br><span class=\"where\">where{where_preds}</span>")
                 } else {
                     let mut clause = br_with_padding;
                     clause.truncate(clause.len() - 5 * "&nbsp;".len());
-                    write!(clause, " <span class=\"where\">where{where_preds}</span>")?;
+                    write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
                     clause
                 }
             }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 6272f47f460ca..bff12e6fee9bd 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1739,8 +1739,8 @@ pub(crate) fn render_impl_summary(
     // in documentation pages for trait with automatic implementations like "Send" and "Sync".
     aliases: &[String],
 ) {
-    let id =
-        cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx));
+    let inner_impl = i.inner_impl();
+    let id = cx.derive_id(get_id_for_impl(&inner_impl.for_, inner_impl.trait_.as_ref(), cx));
     let aliases = if aliases.is_empty() {
         String::new()
     } else {
@@ -1752,9 +1752,9 @@ pub(crate) fn render_impl_summary(
     write!(w, "<h3 class=\"code-header in-band\">");
 
     if let Some(use_absolute) = use_absolute {
-        write!(w, "{}", i.inner_impl().print(use_absolute, cx));
+        write!(w, "{}", inner_impl.print(use_absolute, cx));
         if show_def_docs {
-            for it in &i.inner_impl().items {
+            for it in &inner_impl.items {
                 if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
                     w.write_str("<span class=\"where fmt-newline\">  ");
                     assoc_type(
@@ -1772,11 +1772,11 @@ pub(crate) fn render_impl_summary(
             }
         }
     } else {
-        write!(w, "{}", i.inner_impl().print(false, cx));
+        write!(w, "{}", inner_impl.print(false, cx));
     }
     write!(w, "</h3>");
 
-    let is_trait = i.inner_impl().trait_.is_some();
+    let is_trait = inner_impl.trait_.is_some();
     if is_trait {
         if let Some(portability) = portability(&i.impl_item, Some(parent)) {
             write!(w, "<span class=\"item-info\">{}</span>", portability);

From 4304d1d1e6ea31ca45b722047f516322af4305c4 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Wed, 31 Aug 2022 17:05:46 +0200
Subject: [PATCH 11/19] Update rustdoc tests

---
 src/test/rustdoc-gui/src/lib2/lib.rs          | 27 +++++++++++++++++++
 .../const-generics/const-generics-docs.rs     |  8 +++---
 .../rustdoc/generic-associated-types/gats.rs  |  4 +--
 .../rustdoc/higher-ranked-trait-bounds.rs     |  8 +++---
 src/test/rustdoc/impl-parts.rs                |  4 +--
 src/test/rustdoc/issue-20727-4.rs             |  4 +--
 src/test/rustdoc/issue-21801.rs               |  2 +-
 src/test/rustdoc/issue-29503.rs               |  2 +-
 src/test/rustdoc/issue-34928.rs               |  2 +-
 src/test/rustdoc/issue-50159.rs               |  4 +--
 src/test/rustdoc/issue-51236.rs               |  2 +-
 src/test/rustdoc/issue-54705.rs               |  6 ++---
 src/test/rustdoc/issue-98697.rs               |  2 +-
 .../rustdoc/primitive-slice-auto-trait.rs     |  4 +--
 src/test/rustdoc/synthetic_auto/basic.rs      |  4 +--
 src/test/rustdoc/synthetic_auto/complex.rs    |  2 +-
 src/test/rustdoc/synthetic_auto/lifetimes.rs  |  4 +--
 src/test/rustdoc/synthetic_auto/manual.rs     |  2 +-
 src/test/rustdoc/synthetic_auto/nested.rs     |  4 +--
 .../rustdoc/synthetic_auto/no-redundancy.rs   |  2 +-
 src/test/rustdoc/synthetic_auto/project.rs    |  4 +--
 .../synthetic_auto/self-referential.rs        |  2 +-
 .../rustdoc/synthetic_auto/static-region.rs   |  2 +-
 src/test/rustdoc/where-clause-order.rs        |  2 +-
 src/test/rustdoc/where.rs                     | 22 +++++++--------
 25 files changed, 77 insertions(+), 52 deletions(-)

diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
index 87f91be3ac82c..7f3172878bfb5 100644
--- a/src/test/rustdoc-gui/src/lib2/lib.rs
+++ b/src/test/rustdoc-gui/src/lib2/lib.rs
@@ -143,3 +143,30 @@ pub struct LongItemInfo2;
 /// Some docs.
 #[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
 impl SimpleTrait for LongItemInfo2 {}
+
+pub struct WhereWhitespace<T>;
+
+impl<T> WhereWhitespace<T> {
+    pub fn new<F>(f: F) -> Self
+    where
+        F: FnMut() -> i32,
+    {}
+}
+
+impl<K, T> Whitespace<&K> for WhereWhitespace<T>
+where
+    K: std::fmt::Debug,
+{
+    type Output = WhereWhitespace<T>;
+    fn index(&self, _key: &K) -> &Self::Output {
+        self
+    }
+}
+
+pub trait Whitespace<Idx>
+where
+    Idx: ?Sized,
+{
+    type Output;
+    fn index(&self, index: Idx) -> &Self::Output;
+}
diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs
index 352a8e646bb49..87d2f29e26055 100644
--- a/src/test/rustdoc/const-generics/const-generics-docs.rs
+++ b/src/test/rustdoc/const-generics/const-generics-docs.rs
@@ -31,12 +31,12 @@ impl Trait<{1 + 2}> for u8 {}
 impl<const N: usize> Trait<N> for [u8; N] {}
 
 // @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
-//      'pub struct Foo<const N: usize> where u8: Trait<N>'
+//      'pub struct Foo<const N: usize>where u8: Trait<N>'
 pub struct Foo<const N: usize> where u8: Trait<N>;
 // @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
 pub struct Bar<T, const N: usize>([T; N]);
 
-// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
+// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M>where u8: Trait<M>'
 impl<const M: usize> Foo<M> where u8: Trait<M> {
     // @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
     pub const FOO_ASSOC: usize = M + 13;
@@ -50,14 +50,14 @@ impl<const M: usize> Foo<M> where u8: Trait<M> {
 // @has foo/struct.Bar.html '//*[@id="impl-Bar%3Cu8%2C%20M%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
 impl<const M: usize> Bar<u8, M> {
     // @has - '//*[@id="method.hey"]' \
-    //      'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'
+    //      'pub fn hey<const N: usize>(&self) -> Foo<N>where u8: Trait<N>'
     pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N> {
         Foo
     }
 }
 
 // @has foo/fn.test.html '//pre[@class="rust fn"]' \
-//      'pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N>'
+//      'pub fn test<const N: usize>() -> impl Trait<N>where u8: Trait<N>'
 pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
     2u8
 }
diff --git a/src/test/rustdoc/generic-associated-types/gats.rs b/src/test/rustdoc/generic-associated-types/gats.rs
index ae981b9499a67..2b9d4952d04ee 100644
--- a/src/test/rustdoc/generic-associated-types/gats.rs
+++ b/src/test/rustdoc/generic-associated-types/gats.rs
@@ -3,7 +3,7 @@
 
 // @has foo/trait.LendingIterator.html
 pub trait LendingIterator {
-    // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a"
+    // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a"
     type Item<'a> where Self: 'a;
 
     // @has - '//*[@id="tymethod.next"]//h4[@class="code-header"]' \
@@ -24,7 +24,7 @@ impl LendingIterator for () {
 pub struct Infinite<T>(T);
 
 // @has foo/trait.LendingIterator.html
-// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a = &'a T"
+// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a = &'a T"
 impl<T> LendingIterator for Infinite<T> {
     type Item<'a> where Self: 'a = &'a T;
 
diff --git a/src/test/rustdoc/higher-ranked-trait-bounds.rs b/src/test/rustdoc/higher-ranked-trait-bounds.rs
index b75b8de52f9cb..59b5b6e5797cc 100644
--- a/src/test/rustdoc/higher-ranked-trait-bounds.rs
+++ b/src/test/rustdoc/higher-ranked-trait-bounds.rs
@@ -4,7 +4,7 @@
 pub trait Trait<'x> {}
 
 // @has foo/fn.test1.html
-// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
+// @has - '//pre' "pub fn test1<T>()where for<'a> &'a T: Iterator,"
 pub fn test1<T>()
 where
     for<'a> &'a T: Iterator,
@@ -12,7 +12,7 @@ where
 }
 
 // @has foo/fn.test2.html
-// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: Trait<'b>,"
+// @has - '//pre' "pub fn test2<T>()where for<'a, 'b> &'a T: Trait<'b>,"
 pub fn test2<T>()
 where
     for<'a, 'b> &'a T: Trait<'b>,
@@ -20,7 +20,7 @@ where
 }
 
 // @has foo/fn.test3.html
-// @has - '//pre' "pub fn test3<F>() where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
+// @has - '//pre' "pub fn test3<F>()where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
 pub fn test3<F>()
 where
     F: for<'a, 'b> Fn(&'a u8, &'b u8),
@@ -38,7 +38,7 @@ pub struct Foo<'a> {
 // @has - '//span[@id="structfield.some_trait"]' "some_trait: &'a dyn for<'b> Trait<'b>"
 
 impl<'a> Foo<'a> {
-    // @has - '//h4[@class="code-header"]' "pub fn bar<T>() where T: Trait<'a>,"
+    // @has - '//h4[@class="code-header"]' "pub fn bar<T>()where T: Trait<'a>,"
     pub fn bar<T>()
     where
         T: Trait<'a>,
diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs
index 249158c1a1f89..b1481e1f27978 100644
--- a/src/test/rustdoc/impl-parts.rs
+++ b/src/test/rustdoc/impl-parts.rs
@@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {}
 pub struct Foo<T> { field: T }
 
 // @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-//     "impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync,"
+//     "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
 // @has impl_parts/trait.AnAutoTrait.html '//*[@class="item-list"]//h3[@class="code-header in-band"]' \
-//     "impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync,"
+//     "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
 impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {}
diff --git a/src/test/rustdoc/issue-20727-4.rs b/src/test/rustdoc/issue-20727-4.rs
index 84fc6f94a265a..643f938759093 100644
--- a/src/test/rustdoc/issue-20727-4.rs
+++ b/src/test/rustdoc/issue-20727-4.rs
@@ -25,7 +25,7 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
 
 pub mod reexport {
     // @has issue_20727_4/reexport/trait.Index.html
-    // @has - '//*[@class="rust trait"]' 'trait Index<Idx> where Idx: ?Sized, {'
+    // @has - '//*[@class="rust trait"]' 'trait Index<Idx>where Idx: ?Sized,{'
     // @has - '//*[@class="rust trait"]' 'type Output: ?Sized'
     // @has - '//*[@class="rust trait"]' \
     //        'fn index(&self, index: Idx) -> &Self::Output'
@@ -33,7 +33,7 @@ pub mod reexport {
 
     // @has issue_20727_4/reexport/trait.IndexMut.html
     // @has - '//*[@class="rust trait"]' \
-    //        'trait IndexMut<Idx>: Index<Idx> where Idx: ?Sized, {'
+    //        'trait IndexMut<Idx>: Index<Idx>where Idx: ?Sized,{'
     // @has - '//*[@class="rust trait"]' \
     //        'fn index_mut(&mut self, index: Idx) -> &mut Self::Output;'
     pub use issue_20727::IndexMut;
diff --git a/src/test/rustdoc/issue-21801.rs b/src/test/rustdoc/issue-21801.rs
index 2a586b6ff6cdc..29d2ec64c206d 100644
--- a/src/test/rustdoc/issue-21801.rs
+++ b/src/test/rustdoc/issue-21801.rs
@@ -5,5 +5,5 @@ extern crate issue_21801;
 
 // @has issue_21801/struct.Foo.html
 // @has - '//*[@id="method.new"]' \
-//        'fn new<F>(f: F) -> Foo where F: FnMut() -> i32'
+//        'fn new<F>(f: F) -> Foowhere F: FnMut() -> i32'
 pub use issue_21801::Foo;
diff --git a/src/test/rustdoc/issue-29503.rs b/src/test/rustdoc/issue-29503.rs
index 635c3175f8138..134821e1ef3ea 100644
--- a/src/test/rustdoc/issue-29503.rs
+++ b/src/test/rustdoc/issue-29503.rs
@@ -5,7 +5,7 @@ pub trait MyTrait {
     fn my_string(&self) -> String;
 }
 
-// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for T where T: Debug"
+// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for Twhere T: Debug"
 impl<T> MyTrait for T
 where
     T: fmt::Debug,
diff --git a/src/test/rustdoc/issue-34928.rs b/src/test/rustdoc/issue-34928.rs
index 4184086f622ab..91b67757453d2 100644
--- a/src/test/rustdoc/issue-34928.rs
+++ b/src/test/rustdoc/issue-34928.rs
@@ -2,5 +2,5 @@
 
 pub trait Bar {}
 
-// @has foo/struct.Foo.html '//pre' 'pub struct Foo<T>(pub T) where T: Bar;'
+// @has foo/struct.Foo.html '//pre' 'pub struct Foo<T>(pub T)where T: Bar;'
 pub struct Foo<T>(pub T) where T: Bar;
diff --git a/src/test/rustdoc/issue-50159.rs b/src/test/rustdoc/issue-50159.rs
index d88c29217023a..43fb705f58994 100644
--- a/src/test/rustdoc/issue-50159.rs
+++ b/src/test/rustdoc/issue-50159.rs
@@ -11,8 +11,8 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
 }
 
 // @has issue_50159/struct.Switch.html
-// @has - '//h3[@class="code-header in-band"]' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
-// @has - '//h3[@class="code-header in-band"]' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
+// @has - '//h3[@class="code-header in-band"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
+// @has - '//h3[@class="code-header in-band"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
 // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
 pub struct Switch<B: Signal> {
diff --git a/src/test/rustdoc/issue-51236.rs b/src/test/rustdoc/issue-51236.rs
index ee11ccc681163..aa5890a84514f 100644
--- a/src/test/rustdoc/issue-51236.rs
+++ b/src/test/rustdoc/issue-51236.rs
@@ -8,7 +8,7 @@ pub mod traits {
 
 // @has issue_51236/struct.Owned.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Owned<T> where <T as Owned<'static>>::Reader: Send"
+// "impl<T> Send for Owned<T>where <T as Owned<'static>>::Reader: Send"
 pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
     marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,
 }
diff --git a/src/test/rustdoc/issue-54705.rs b/src/test/rustdoc/issue-54705.rs
index bedaf5c4ddc36..ce0f85d25da56 100644
--- a/src/test/rustdoc/issue-54705.rs
+++ b/src/test/rustdoc/issue-54705.rs
@@ -1,13 +1,11 @@
 pub trait ScopeHandle<'scope> {}
 
-
-
 // @has issue_54705/struct.ScopeFutureContents.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'scope, S> Send for ScopeFutureContents<'scope, S> where S: Sync"
+// "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync"
 //
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S> where S: Sync"
+// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync"
 pub struct ScopeFutureContents<'scope, S>
     where S: ScopeHandle<'scope>,
 {
diff --git a/src/test/rustdoc/issue-98697.rs b/src/test/rustdoc/issue-98697.rs
index 83e08094c0953..a8841f137fecf 100644
--- a/src/test/rustdoc/issue-98697.rs
+++ b/src/test/rustdoc/issue-98697.rs
@@ -8,7 +8,7 @@
 
 extern crate issue_98697_reexport_with_anonymous_lifetime;
 
-// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>() where F: Fn(&str)'
+// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>()where F: Fn(&str)'
 // @!has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'for<'
 pub use issue_98697_reexport_with_anonymous_lifetime::repro;
 
diff --git a/src/test/rustdoc/primitive-slice-auto-trait.rs b/src/test/rustdoc/primitive-slice-auto-trait.rs
index b3f511bc1f153..7f8f74ff457a5 100644
--- a/src/test/rustdoc/primitive-slice-auto-trait.rs
+++ b/src/test/rustdoc/primitive-slice-auto-trait.rs
@@ -7,8 +7,8 @@
 // @has - '//span[@class="in-band"]' 'Primitive Type slice'
 // @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
 // @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
-// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T] where T: Send'
-// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T] where T: Sync'
+// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T]where T: Send'
+// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T]where T: Sync'
 #[doc(primitive = "slice")]
 /// this is a test!
 mod slice_prim {}
diff --git a/src/test/rustdoc/synthetic_auto/basic.rs b/src/test/rustdoc/synthetic_auto/basic.rs
index 54c54fdbf68a8..19138fd1aceb2 100644
--- a/src/test/rustdoc/synthetic_auto/basic.rs
+++ b/src/test/rustdoc/synthetic_auto/basic.rs
@@ -1,6 +1,6 @@
 // @has basic/struct.Foo.html
-// @has - '//h3[@class="code-header in-band"]' 'impl<T> Send for Foo<T> where T: Send'
-// @has - '//h3[@class="code-header in-band"]' 'impl<T> Sync for Foo<T> where T: Sync'
+// @has - '//h3[@class="code-header in-band"]' 'impl<T> Send for Foo<T>where T: Send'
+// @has - '//h3[@class="code-header in-band"]' 'impl<T> Sync for Foo<T>where T: Sync'
 // @count - '//*[@id="implementations-list"]//*[@class="impl has-srclink"]' 0
 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
 pub struct Foo<T> {
diff --git a/src/test/rustdoc/synthetic_auto/complex.rs b/src/test/rustdoc/synthetic_auto/complex.rs
index f9017b90caee7..39f78983da2b0 100644
--- a/src/test/rustdoc/synthetic_auto/complex.rs
+++ b/src/test/rustdoc/synthetic_auto/complex.rs
@@ -21,7 +21,7 @@ mod foo {
 
 // @has complex/struct.NotOuter.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
+// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \
 // -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"
 
 pub use foo::{Foo, Inner as NotInner, MyTrait as NotMyTrait, Outer as NotOuter};
diff --git a/src/test/rustdoc/synthetic_auto/lifetimes.rs b/src/test/rustdoc/synthetic_auto/lifetimes.rs
index ee1393f9729c1..0c94850e78608 100644
--- a/src/test/rustdoc/synthetic_auto/lifetimes.rs
+++ b/src/test/rustdoc/synthetic_auto/lifetimes.rs
@@ -10,10 +10,10 @@ where
 
 // @has lifetimes/struct.Foo.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Send for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
+// "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
 //
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Sync for Foo<'c, K> where K: Sync"
+// "impl<'c, K> Sync for Foo<'c, K>where K: Sync"
 pub struct Foo<'c, K: 'c> {
     inner_field: Inner<'c, K>,
 }
diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs
index 49bad162211b7..35047e3e8c071 100644
--- a/src/test/rustdoc/synthetic_auto/manual.rs
+++ b/src/test/rustdoc/synthetic_auto/manual.rs
@@ -1,6 +1,6 @@
 // @has manual/struct.Foo.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// 'impl<T> Sync for Foo<T> where T: Sync'
+// 'impl<T> Sync for Foo<T>where T: Sync'
 //
 // @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
 // 'impl<T> Send for Foo<T>'
diff --git a/src/test/rustdoc/synthetic_auto/nested.rs b/src/test/rustdoc/synthetic_auto/nested.rs
index 69edbee619e31..09587bcc30f13 100644
--- a/src/test/rustdoc/synthetic_auto/nested.rs
+++ b/src/test/rustdoc/synthetic_auto/nested.rs
@@ -10,10 +10,10 @@ where
 
 // @has nested/struct.Foo.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// 'impl<T> Send for Foo<T> where T: Copy'
+// 'impl<T> Send for Foo<T>where T: Copy'
 //
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// 'impl<T> Sync for Foo<T> where T: Sync'
+// 'impl<T> Sync for Foo<T>where T: Sync'
 pub struct Foo<T> {
     inner_field: Inner<T>,
 }
diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs
index 16ab876e829ef..41375decc8a4a 100644
--- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs
+++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs
@@ -10,7 +10,7 @@ where
 
 // @has no_redundancy/struct.Outer.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Outer<T> where T: Send + Copy"
+// "impl<T> Send for Outer<T>where T: Send + Copy"
 pub struct Outer<T> {
     inner_field: Inner<T>,
 }
diff --git a/src/test/rustdoc/synthetic_auto/project.rs b/src/test/rustdoc/synthetic_auto/project.rs
index 8b020582563f3..e80b1b1dc9bcf 100644
--- a/src/test/rustdoc/synthetic_auto/project.rs
+++ b/src/test/rustdoc/synthetic_auto/project.rs
@@ -24,10 +24,10 @@ where
 
 // @has project/struct.Foo.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Send for Foo<'c, K> where K: MyTrait<MyItem = bool>, 'c: 'static"
+// "impl<'c, K> Send for Foo<'c, K>where K: MyTrait<MyItem = bool>, 'c: 'static"
 //
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<'c, K> Sync for Foo<'c, K> where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
+// "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
 // 'c: 'static,"
 pub struct Foo<'c, K: 'c> {
     inner_field: Inner<'c, K>,
diff --git a/src/test/rustdoc/synthetic_auto/self-referential.rs b/src/test/rustdoc/synthetic_auto/self-referential.rs
index ccef901b18da3..d15a8de7d2fe1 100644
--- a/src/test/rustdoc/synthetic_auto/self-referential.rs
+++ b/src/test/rustdoc/synthetic_auto/self-referential.rs
@@ -24,6 +24,6 @@ impl<T> Pattern for Wrapper<T> {
 
 // @has self_referential/struct.WriteAndThen.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<P1> Send for WriteAndThen<P1>  where  <P1 as Pattern>::Value: Send"
+// "impl<P1> Send for WriteAndThen<P1>where    <P1 as Pattern>::Value: Send"
 pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
     where P1: Pattern;
diff --git a/src/test/rustdoc/synthetic_auto/static-region.rs b/src/test/rustdoc/synthetic_auto/static-region.rs
index 36e985144b0e0..08e9567313e22 100644
--- a/src/test/rustdoc/synthetic_auto/static-region.rs
+++ b/src/test/rustdoc/synthetic_auto/static-region.rs
@@ -4,7 +4,7 @@ pub trait OwnedTrait<'a> {
 
 // @has static_region/struct.Owned.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Owned<T> where <T as OwnedTrait<'static>>::Reader: Send"
+// "impl<T> Send for Owned<T>where <T as OwnedTrait<'static>>::Reader: Send"
 pub struct Owned<T> where T: OwnedTrait<'static> {
     marker: <T as OwnedTrait<'static>>::Reader,
 }
diff --git a/src/test/rustdoc/where-clause-order.rs b/src/test/rustdoc/where-clause-order.rs
index 3150a8ea05f41..b8502e10a48c4 100644
--- a/src/test/rustdoc/where-clause-order.rs
+++ b/src/test/rustdoc/where-clause-order.rs
@@ -7,7 +7,7 @@ where
 }
 
 // @has 'foo/trait.SomeTrait.html'
-// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
+// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
 impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)
 where
     A: PartialOrd<A> + PartialEq<A>,
diff --git a/src/test/rustdoc/where.rs b/src/test/rustdoc/where.rs
index 50a5722fbaff6..c1a630e25ba0e 100644
--- a/src/test/rustdoc/where.rs
+++ b/src/test/rustdoc/where.rs
@@ -3,17 +3,17 @@
 
 pub trait MyTrait { fn dummy(&self) { } }
 
-// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_) where A: MyTrait"
+// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_)where A: MyTrait"
 pub struct Alpha<A>(A) where A: MyTrait;
-// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B> where B: MyTrait"
+// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B>where B: MyTrait"
 pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
-// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>() where C: MyTrait"
+// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>()where C: MyTrait"
 pub fn charlie<C>() where C: MyTrait {}
 
 pub struct Delta<D>(D);
 
 // @has foo/struct.Delta.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-//          "impl<D> Delta<D> where D: MyTrait"
+//          "impl<D> Delta<D>where D: MyTrait"
 impl<D> Delta<D> where D: MyTrait {
     pub fn delta() {}
 }
@@ -33,19 +33,19 @@ pub trait TraitWhere {
 }
 
 // @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-//          "impl<E> MyTrait for Echo<E> where E: MyTrait"
+//          "impl<E> MyTrait for Echo<E>where E: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
-//          "impl<E> MyTrait for Echo<E> where E: MyTrait"
-impl<E> MyTrait for Echo<E> where E: MyTrait {}
+//          "impl<E> MyTrait for Echo<E>where E: MyTrait"
+impl<E> MyTrait for Echo<E>where E: MyTrait {}
 
 pub enum Foxtrot<F> { Foxtrot1(F) }
 
 // @has foo/enum.Foxtrot.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-//          "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
+//          "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
-//          "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
-impl<F> MyTrait for Foxtrot<F> where F: MyTrait {}
+//          "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
+impl<F> MyTrait for Foxtrot<F>where F: MyTrait {}
 
 // @has foo/type.Golf.html '//pre[@class="rust typedef"]' \
-//          "type Golf<T> where T: Clone, = (T, T)"
+//          "type Golf<T>where T: Clone, = (T, T)"
 pub type Golf<T> where T: Clone = (T, T);

From b112bfeda9dba77c6d7e8eef92125e7002c43e68 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Wed, 31 Aug 2022 18:13:59 +0200
Subject: [PATCH 12/19] Add rustdoc GUI test

---
 src/test/rustdoc-gui/where-whitespace.goml | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 src/test/rustdoc-gui/where-whitespace.goml

diff --git a/src/test/rustdoc-gui/where-whitespace.goml b/src/test/rustdoc-gui/where-whitespace.goml
new file mode 100644
index 0000000000000..1a3ff1f491cbb
--- /dev/null
+++ b/src/test/rustdoc-gui/where-whitespace.goml
@@ -0,0 +1,27 @@
+// This test ensures that the where conditions are correctly displayed.
+goto: file://|DOC_PATH|/lib2/trait.Whitespace.html
+show-text: true
+// First, we check in the trait definition if the where clause is "on its own" (not on the same
+// line than "pub trait Whitespace<Idx>").
+compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y"))
+// And that the code following it isn't on the same line either.
+compare-elements-position-false: (".item-decl .fnname", ".where.fmt-newline", ("y"))
+
+goto: file://|DOC_PATH|/lib2/struct.WhereWhitespace.html
+// We make the screen a bit wider to ensure that the trait impl is on one line.
+size: (915, 915)
+
+compare-elements-position-false: ("#method\.new .fnname", "#method\.new .where.fmt-newline", ("y"))
+// We ensure that both the trait name and the struct name are on the same line in
+// "impl<K, T> Whitespace<&K> for WhereWhitespace<T>".
+compare-elements-position: (
+    "#trait-implementations-list .impl h3 .trait",
+    "#trait-implementations-list .impl h3 .struct",
+    ("y"),
+)
+// And we now check that the where condition isn't on the same line.
+compare-elements-position-false: (
+    "#trait-implementations-list .impl h3 .trait",
+    "#trait-implementations-list .impl h3 .where.fmt-newline",
+    ("y"),
+)

From a928255ab1c6a594faa15f93d912c1179ae354ea Mon Sep 17 00:00:00 2001
From: Matt Hamrick <matthewjhamrick@gmail.com>
Date: Wed, 31 Aug 2022 13:21:47 -0700
Subject: [PATCH 13/19] Fix  bad target name in Walkthrough

Walkthrough currently say:

```
rustup target add aarch_64-fuchsia
```
but should say

```
rustup target add aarch64-fuchsia
```
---
 src/doc/rustc/src/platform-support/fuchsia.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index c2a1613f288c5..94373b01cc469 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -79,7 +79,7 @@ the following commands:
 
 ```sh
 rustup target add x86_64-fuchsia
-rustup target add aarch_64-fuchsia
+rustup target add aarch64-fuchsia
 ```
 
 After installing our Fuchsia targets, we can now compile a Rust binary that targets

From 037a911bd8f223a15a500c172e1b8d030c9a05f3 Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Wed, 31 Aug 2022 10:06:48 -0700
Subject: [PATCH 14/19] rustdoc: remove unused `.docblock .impl-items` CSS

The impl-items list stopped being nested inside a docblock since c1b1d6804bfce1aee3a95b3cbff3eaeb15bad9a4
---
 src/librustdoc/html/static/css/rustdoc.css | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index c117e3ac40dab..00d2300877284 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -759,14 +759,6 @@ pre, .rustdoc.source .example-wrap {
 	margin-bottom: 15px;
 }
 
-.content .docblock > .impl-items {
-	margin-left: 20px;
-	margin-top: -34px;
-}
-.content .docblock >.impl-items table td {
-	padding: 0;
-}
-
 .item-info {
 	display: block;
 }

From d8b572b820e2c1b59a26d28fc2c6234e34aedc6d Mon Sep 17 00:00:00 2001
From: Andrew Pollack <andrewpkq@gmail.com>
Date: Wed, 31 Aug 2022 23:49:48 +0000
Subject: [PATCH 15/19] Tweaks to fuchsia doc walkthrough

---
 src/doc/rustc/src/platform-support/fuchsia.md | 28 ++++++++++++-------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index c2a1613f288c5..10d12f88454d1 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -125,13 +125,20 @@ during compilation:
 [target.x86_64-fuchsia]
 
 rustflags = [
-    "-Lnative", "<SDK_PATH>/arch/x64/sysroot/lib",
-    "-Lnative", "<SDK_PATH>/arch/x64/lib"
+    "-Lnative=<SDK_PATH>/arch/x64/lib",
+    "-Lnative=<SDK_PATH>/arch/x64/sysroot/lib"
 ]
 ```
 
 *Note: Make sure to fill out `<SDK_PATH>` with the path to the downloaded [Fuchsia SDK].*
 
+These options configure the following:
+
+* `-Lnative=${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
+  the SDK
+* `-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel
+  libraries from the SDK
+
 In total, our new project will look like:
 
 **Current directory structure**
@@ -368,6 +375,7 @@ language called CML. The Fuchsia devsite contains an [overview of CML] and a
 }
 ```
 
+**Current directory structure**
 ```txt
 hello_fuchsia/
 ┗━ pkg/
@@ -386,6 +394,9 @@ ${SDK_PATH}/tools/${ARCH}/cmc compile \
     -o pkg/meta/hello_fuchsia.cm
 ```
 
+*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
+In our case, we're only using `syslog/client.shard.cml`.*
+
 **Current directory structure**
 ```txt
 hello_fuchsia/
@@ -397,19 +408,16 @@ hello_fuchsia/
    ┗━ hello_fuchsia.cml
 ```
 
-*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
-In our case, we're only using `syslog/client.shard.cml`.*
-
 ### Building a Fuchsia package
 
 Next, we'll build a package manifest as defined by our manifest:
 
 ```sh
 ${SDK_PATH}/tools/${ARCH}/pm \
-    -o hello_fuchsia_manifest \
+    -o pkg/hello_fuchsia_manifest \
     -m pkg/hello_fuchsia.manifest \
     build \
-    -output-package-manifest hello_fuchsia_package_manifest
+    -output-package-manifest pkg/hello_fuchsia_package_manifest
 ```
 
 This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
@@ -469,15 +477,15 @@ We can publish our new package to that repository with:
 
 ```sh
 ${SDK_PATH}/tools/${ARCH}/pm publish \
-    -repo repo \
-    -lp -f <(echo "hello_fuchsia_package_manifest")
+    -repo pkg/repo \
+    -lp -f <(echo "pkg/hello_fuchsia_package_manifest")
 ```
 
 Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
 
 ```sh
 ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
-    repo \
+    pkg/repo \
     -r hello-fuchsia
 ```
 

From a20318d94ba68151a97d585b870915d3e2f9da58 Mon Sep 17 00:00:00 2001
From: Mara Bos <m-ou.se@m-ou.se>
Date: Thu, 1 Sep 2022 11:20:08 +0200
Subject: [PATCH 16/19] Update outdated comment about output capturing in
 print_to.

---
 library/std/src/io/stdio.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 4d3736f79146c..07239746258d1 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -986,10 +986,10 @@ pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
 /// otherwise. `label` identifies the stream in a panic message.
 ///
 /// This function is used to print error messages, so it takes extra
-/// care to avoid causing a panic when `local_s` is unusable.
-/// For instance, if the TLS key for the local stream is
-/// already destroyed, or if the local stream is locked by another
-/// thread, it will just fall back to the global stream.
+/// care to avoid causing a panic when `OUTPUT_CAPTURE` is unusable.
+/// For instance, if the TLS key for output capturing is already destroyed, or
+/// if the local stream is in use by another thread, it will just fall back to
+/// the global stream.
 ///
 /// However, if the actual I/O causes an error, this function does panic.
 fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)

From 098725c2e2b943b5b84c4a3a0a9f49e900a51954 Mon Sep 17 00:00:00 2001
From: Quinn Painter <quinn@geekymonkey.com>
Date: Thu, 1 Sep 2022 10:23:15 +0100
Subject: [PATCH 17/19] Fix filename of armv4t-none-eabi.md

The filename differed from the link in SUMMARY.md, causing it to 404.
---
 .../platform-support/{armv4t_none_eabi.md => armv4t-none-eabi.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename src/doc/rustc/src/platform-support/{armv4t_none_eabi.md => armv4t-none-eabi.md} (100%)

diff --git a/src/doc/rustc/src/platform-support/armv4t_none_eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
similarity index 100%
rename from src/doc/rustc/src/platform-support/armv4t_none_eabi.md
rename to src/doc/rustc/src/platform-support/armv4t-none-eabi.md

From c9f4af6e11ce44a3ab5de838279295be3df3aa95 Mon Sep 17 00:00:00 2001
From: Nixon Enraght-Moony <nixon.emoony@gmail.com>
Date: Thu, 1 Sep 2022 12:09:42 +0100
Subject: [PATCH 18/19] Fix typo in comment

---
 src/librustdoc/passes/stripper.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 83ed3752a824c..a9d768f0149d6 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -91,7 +91,7 @@ impl<'a> DocFolder for Stripper<'a> {
             clean::ExternCrateItem { .. } => {}
             clean::ImportItem(ref imp) => {
                 // Because json doesn't inline imports from private modules, we need to mark
-                // the imported item as retained so it's impls won't be stripped.i
+                // the imported item as retained so it's impls won't be stripped.
                 //
                 // FIXME: Is it necessary to check for json output here: See
                 // https://github.com/rust-lang/rust/pull/100325#discussion_r941495215

From 78e9bea598a1e9a87236e9bf437baa8f9ecb8294 Mon Sep 17 00:00:00 2001
From: Takayuki Maeda <takoyaki0316@gmail.com>
Date: Thu, 1 Sep 2022 23:50:51 +0900
Subject: [PATCH 19/19] do not suggest adding `move` to closure when `move` is
 already used

---
 .../src/diagnostics/region_errors.rs           | 14 +++++++++++---
 ...e-when-closure-is-already-marked-as-move.rs |  8 ++++++++
 ...en-closure-is-already-marked-as-move.stderr | 18 ++++++++++++++++++
 3 files changed, 37 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs
 create mode 100644 src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr

diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 00fdf331ca60c..082dd86902354 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -902,7 +902,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             hir::ExprKind::MethodCall(.., args, _) => {
                 // only the first closre parameter of the method. args[0] is MethodCall PathSegment
                 for i in 1..args.len() {
-                    if let hir::ExprKind::Closure(..) = args[i].kind {
+                    if let hir::ExprKind::Closure(hir::Closure {
+                        capture_clause: hir::CaptureBy::Ref,
+                        ..
+                    }) = args[i].kind
+                    {
                         closure_span = Some(args[i].span.shrink_to_lo());
                         break;
                     }
@@ -911,7 +915,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             hir::ExprKind::Block(blk, _) => {
                 if let Some(ref expr) = blk.expr {
                     // only when the block is a closure
-                    if let hir::ExprKind::Closure(..) = expr.kind {
+                    if let hir::ExprKind::Closure(hir::Closure {
+                        capture_clause: hir::CaptureBy::Ref,
+                        ..
+                    }) = expr.kind
+                    {
                         closure_span = Some(expr.span.shrink_to_lo());
                     }
                 }
@@ -921,7 +929,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         if let Some(closure_span) = closure_span {
             diag.span_suggestion_verbose(
                 closure_span,
-                format!("consider adding 'move' keyword before the nested closure"),
+                "consider adding 'move' keyword before the nested closure",
                 "move ",
                 Applicability::MaybeIncorrect,
             );
diff --git a/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs
new file mode 100644
index 0000000000000..524459291f853
--- /dev/null
+++ b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let mut vec: Vec<i32> = Vec::new();
+    let closure = move || {
+        vec.clear();
+        let mut iter = vec.iter();
+        move || { iter.next() } //~ ERROR captured variable cannot escape `FnMut` closure bod
+    };
+}
diff --git a/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr
new file mode 100644
index 0000000000000..78ca090feb722
--- /dev/null
+++ b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr
@@ -0,0 +1,18 @@
+error: captured variable cannot escape `FnMut` closure body
+  --> $DIR/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs:6:9
+   |
+LL |     let mut vec: Vec<i32> = Vec::new();
+   |         ------- variable defined here
+LL |     let closure = move || {
+   |                         - inferred to be a `FnMut` closure
+LL |         vec.clear();
+   |         --- variable captured here
+LL |         let mut iter = vec.iter();
+LL |         move || { iter.next() }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+   |
+   = note: `FnMut` closures only have access to their captured variables while they are executing...
+   = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+