diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 36362635b1545..fe67a14c0fe45 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -263,6 +263,7 @@ jobs:
             env:
               IMAGE: x86_64-gnu
               RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
+              CI_ONLY_WHEN_CHANNEL: nightly
             os: ubuntu-latest-xl
           - name: x86_64-gnu-aux
             os: ubuntu-latest-xl
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 6f65d386f0d1b..65999ba707c85 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -248,6 +248,7 @@ E0493: include_str!("./error_codes/E0493.md"),
 E0495: include_str!("./error_codes/E0495.md"),
 E0496: include_str!("./error_codes/E0496.md"),
 E0497: include_str!("./error_codes/E0497.md"),
+E0498: include_str!("./error_codes/E0498.md"),
 E0499: include_str!("./error_codes/E0499.md"),
 E0500: include_str!("./error_codes/E0500.md"),
 E0501: include_str!("./error_codes/E0501.md"),
@@ -604,7 +605,6 @@ E0783: include_str!("./error_codes/E0783.md"),
 //  E0488, // lifetime of variable does not enclose its declaration
 //  E0489, // type/lifetime parameter not in scope here
     E0490, // a value of type `..` is borrowed for too long
-    E0498,  // malformed plugin attribute
     E0514, // metadata version mismatch
     E0519, // local crate and dependency have same (crate-name, disambiguator)
     // two dependencies have same (crate-name, disambiguator) but different SVH
diff --git a/compiler/rustc_error_codes/src/error_codes/E0498.md b/compiler/rustc_error_codes/src/error_codes/E0498.md
new file mode 100644
index 0000000000000..c9ea4a7947f6c
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0498.md
@@ -0,0 +1,22 @@
+The `plugin` attribute was malformed.
+
+Erroneous code example:
+
+```compile_fail,E0498
+#![feature(plugin)]
+#![plugin(foo(args))] // error: invalid argument
+#![plugin(bar="test")] // error: invalid argument
+```
+
+The `#[plugin]` attribute should take a single argument: the name of the plugin.
+
+For example, for the plugin `foo`:
+
+```ignore (requires external plugin crate)
+#![feature(plugin)]
+#![plugin(foo)] // ok!
+```
+
+See the [`plugin` feature] section of the Unstable book for more details.
+
+[`plugin` feature]: https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html
diff --git a/compiler/rustc_error_codes/src/error_codes/E0617.md b/compiler/rustc_error_codes/src/error_codes/E0617.md
index 1c5d1f87b912b..eed384b495946 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0617.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0617.md
@@ -3,12 +3,13 @@ Attempted to pass an invalid type of variable into a variadic function.
 Erroneous code example:
 
 ```compile_fail,E0617
+# use std::os::raw::{c_char, c_int};
 extern "C" {
-    fn printf(c: *const i8, ...);
+    fn printf(format: *const c_char, ...) -> c_int;
 }
 
 unsafe {
-    printf(::std::ptr::null(), 0f32);
+    printf("%f\n\0".as_ptr() as _, 0f32);
     // error: cannot pass an `f32` to variadic function, cast to `c_double`
 }
 ```
@@ -21,10 +22,12 @@ to import from `std::os::raw`).
 In this case, `c_double` has the same size as `f64` so we can use it directly:
 
 ```no_run
+# use std::os::raw::{c_char, c_int};
 # extern "C" {
-#     fn printf(c: *const i8, ...);
+#     fn printf(format: *const c_char, ...) -> c_int;
 # }
+
 unsafe {
-    printf(::std::ptr::null(), 0f64); // ok!
+    printf("%f\n\0".as_ptr() as _, 0f64); // ok!
 }
 ```
diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs
index 3fbc81d5426ee..e58a7d903082e 100644
--- a/compiler/rustc_mir/src/transform/mod.rs
+++ b/compiler/rustc_mir/src/transform/mod.rs
@@ -259,10 +259,12 @@ fn mir_const<'tcx>(
     }
 
     // Unsafety check uses the raw mir, so make sure it is run.
-    if let Some(param_did) = def.const_param_did {
-        tcx.ensure().unsafety_check_result_for_const_arg((def.did, param_did));
-    } else {
-        tcx.ensure().unsafety_check_result(def.did);
+    if !tcx.sess.opts.debugging_opts.thir_unsafeck {
+        if let Some(param_did) = def.const_param_did {
+            tcx.ensure().unsafety_check_result_for_const_arg((def.did, param_did));
+        } else {
+            tcx.ensure().unsafety_check_result(def.did);
+        }
     }
 
     let mut body = tcx.mir_built(def).steal();
diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs
index 15952c6806fa4..7cd0ce9d2efe0 100644
--- a/library/core/src/future/future.rs
+++ b/library/core/src/future/future.rs
@@ -111,11 +111,11 @@ impl<F: ?Sized + Future + Unpin> Future for &mut F {
 #[stable(feature = "futures_api", since = "1.36.0")]
 impl<P> Future for Pin<P>
 where
-    P: Unpin + ops::DerefMut<Target: Future>,
+    P: ops::DerefMut<Target: Future>,
 {
     type Output = <<P as ops::Deref>::Target as Future>::Output;
 
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        Pin::get_mut(self).as_mut().poll(cx)
+        <P::Target as Future>::poll(self.as_deref_mut(), cx)
     }
 }
diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs
index b0c7fbb1d7a76..cc905d288f9e0 100644
--- a/library/core/src/future/ready.rs
+++ b/library/core/src/future/ready.rs
@@ -20,7 +20,7 @@ impl<T> Future for Ready<T> {
 
     #[inline]
     fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
-        Poll::Ready(self.0.take().expect("Ready polled after completion"))
+        Poll::Ready(self.0.take().expect("`Ready` polled after completion"))
     }
 }
 
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 839be5a143f71..f7d48a91396ff 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -128,6 +128,7 @@
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
 #![feature(auto_traits)]
+#![feature(pin_deref_mut)]
 #![feature(prelude_import)]
 #![feature(ptr_metadata)]
 #![feature(repr_simd, platform_intrinsics)]
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 3d888299485b5..6b1a12ed18c0f 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -802,6 +802,44 @@ impl<T: ?Sized> Pin<&'static T> {
     }
 }
 
+impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
+    /// Gets a pinned mutable reference from this nested pinned pointer.
+    ///
+    /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
+    /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
+    /// move in the future, and this method does not enable the pointee to move. "Malicious"
+    /// implementations of `P::DerefMut` are likewise ruled out by the contract of
+    /// `Pin::new_unchecked`.
+    #[unstable(feature = "pin_deref_mut", issue = "86918")]
+    #[inline(always)]
+    pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> {
+        // SAFETY: What we're asserting here is that going from
+        //
+        //     Pin<&mut Pin<P>>
+        //
+        // to
+        //
+        //     Pin<&mut P::Target>
+        //
+        // is safe.
+        //
+        // We need to ensure that two things hold for that to be the case:
+        //
+        // 1) Once we give out a `Pin<&mut P::Target>`, an `&mut P::Target` will not be given out.
+        // 2) By giving out a `Pin<&mut P::Target>`, we do not risk of violating `Pin<&mut Pin<P>>`
+        //
+        // The existence of `Pin<P>` is sufficient to guarantee #1: since we already have a
+        // `Pin<P>`, it must already uphold the pinning guarantees, which must mean that
+        // `Pin<&mut P::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
+        // on the fact that P is _also_ pinned.
+        //
+        // For #2, we need to ensure that code given a `Pin<&mut P::Target>` cannot cause the
+        // `Pin<P>` to move? That is not possible, since `Pin<&mut P::Target>` no longer retains
+        // any access to the `P` itself, much less the `Pin<P>`.
+        unsafe { self.get_unchecked_mut() }.as_mut()
+    }
+}
+
 impl<T: ?Sized> Pin<&'static mut T> {
     /// Get a pinned mutable reference from a static mutable reference.
     ///
diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs
index 3d6f4f5971a62..5f077f77bbc9f 100644
--- a/library/core/src/task/mod.rs
+++ b/library/core/src/task/mod.rs
@@ -11,5 +11,5 @@ mod wake;
 pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
 
 mod ready;
-#[unstable(feature = "ready_macro", issue = "70922")]
+#[stable(feature = "ready_macro", since = "1.56.0")]
 pub use ready::ready;
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
index cbf6990001589..2834ca5fe2224 100644
--- a/library/core/src/task/ready.rs
+++ b/library/core/src/task/ready.rs
@@ -8,8 +8,6 @@
 /// # Examples
 ///
 /// ```
-/// #![feature(ready_macro)]
-///
 /// use std::task::{ready, Context, Poll};
 /// use std::future::{self, Future};
 /// use std::pin::Pin;
@@ -29,8 +27,6 @@
 /// The `ready!` call expands to:
 ///
 /// ```
-/// # #![feature(ready_macro)]
-/// #
 /// # use std::task::{Context, Poll};
 /// # use std::future::{self, Future};
 /// # use std::pin::Pin;
@@ -49,7 +45,7 @@
 ///     # Poll::Ready(())
 /// # }
 /// ```
-#[unstable(feature = "ready_macro", issue = "70922")]
+#[stable(feature = "ready_macro", since = "1.56.0")]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro ready($e:expr) {
     match $e {
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index bbe1ab40537f2..f72f88bb05c9d 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -1912,6 +1912,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 ///     Ok(())
 /// }
 /// ```
+#[doc(alias = "mkdir")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
     DirBuilder::new().create(path.as_ref())
@@ -1991,6 +1992,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///     Ok(())
 /// }
 /// ```
+#[doc(alias = "rmdir")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::rmdir(path.as_ref())
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index f0e628c3d8363..9cbaa06562a55 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -304,7 +304,6 @@
 #![feature(pin_static_ref)]
 #![feature(prelude_import)]
 #![feature(ptr_internals)]
-#![feature(ready_macro)]
 #![feature(rustc_attrs)]
 #![feature(rustc_private)]
 #![feature(shrink_to)]
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index e704071e401b7..128897e580b68 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -416,6 +416,10 @@ jobs:
             env:
               IMAGE: x86_64-gnu
               RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
+              # Only run this job on the nightly channel. Running this on beta
+              # could cause failures when `dev: 1` in `stage0.txt`, and running
+              # this on stable is useless.
+              CI_ONLY_WHEN_CHANNEL: nightly
             <<: *job-linux-xl
 
           - name: x86_64-gnu-aux
diff --git a/src/ci/scripts/should-skip-this.sh b/src/ci/scripts/should-skip-this.sh
index fa738fe70c8e2..bb48fcb5a216e 100755
--- a/src/ci/scripts/should-skip-this.sh
+++ b/src/ci/scripts/should-skip-this.sh
@@ -8,31 +8,43 @@ IFS=$'\n\t'
 
 source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 
-if [[ -z "${CI_ONLY_WHEN_SUBMODULES_CHANGED+x}" ]]; then
-    echo "Executing the job since there is no skip rule in effect"
-    exit 0
+if [[ -n "${CI_ONLY_WHEN_SUBMODULES_CHANGED-}" ]]; then
+    git fetch "https://github.com/$GITHUB_REPOSITORY" "$GITHUB_BASE_REF"
+    BASE_COMMIT="$(git merge-base FETCH_HEAD HEAD)"
+
+    echo "Searching for toolstate changes between $BASE_COMMIT and $(git rev-parse HEAD)"
+
+    if git diff "$BASE_COMMIT" | grep --quiet "^index .* 160000"; then
+        # Submodules pseudo-files inside git have the 160000 permissions, so when
+        # those files are present in the diff a submodule was updated.
+        echo "Submodules were updated"
+    elif ! git diff --quiet "$BASE_COMMIT" -- src/tools/clippy src/tools/rustfmt; then
+        # There is not an easy blanket search for subtrees. For now, manually list
+        # the subtrees.
+        echo "Clippy or rustfmt subtrees were updated"
+    elif ! (git diff --quiet "$BASE_COMMIT" -- \
+             src/test/rustdoc-gui \
+             src/librustdoc \
+             src/tools/rustdoc-gui); then
+        # There was a change in either rustdoc or in its GUI tests.
+        echo "Rustdoc was updated"
+    else
+        echo "Not executing this job since no submodules nor subtrees were updated"
+        ciCommandSetEnv SKIP_JOB 1
+        exit 0
+    fi
 fi
 
-git fetch "https://github.com/$GITHUB_REPOSITORY" "$GITHUB_BASE_REF"
-BASE_COMMIT="$(git merge-base FETCH_HEAD HEAD)"
-
-echo "Searching for toolstate changes between $BASE_COMMIT and $(git rev-parse HEAD)"
-
-if git diff "$BASE_COMMIT" | grep --quiet "^index .* 160000"; then
-    # Submodules pseudo-files inside git have the 160000 permissions, so when
-    # those files are present in the diff a submodule was updated.
-    echo "Executing the job since submodules are updated"
-elif ! git diff --quiet "$BASE_COMMIT" -- src/tools/clippy src/tools/rustfmt; then
-    # There is not an easy blanket search for subtrees. For now, manually list
-    # the subtrees.
-    echo "Executing the job since clippy or rustfmt subtree was updated"
-elif ! (git diff --quiet "$BASE_COMMIT" -- \
-         src/test/rustdoc-gui \
-         src/librustdoc \
-         src/tools/rustdoc-gui); then
-    # There was a change in either rustdoc or in its GUI tests.
-    echo "Executing the job since rustdoc was updated"
-else
-    echo "Not executing this job since no submodules nor subtrees were updated"
-    ciCommandSetEnv SKIP_JOB 1
+if [[ -n "${CI_ONLY_WHEN_CHANNEL-}" ]]; then
+    if [[ "${CI_ONLY_WHEN_CHANNEL}" = "$(cat src/ci/channel)" ]]; then
+        echo "The channel is the expected one"
+    else
+        echo "Not executing this job as the channel is not the expected one"
+        ciCommandSetEnv SKIP_JOB 1
+        exit 0
+    fi
 fi
+
+
+echo "Executing the job since there is no skip rule preventing the execution"
+exit 0
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 27c2f6cc87e17..fd79292477cab 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1730,9 +1730,13 @@ impl Clean<Variant> for hir::VariantData<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
         match self {
             hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)),
-            hir::VariantData::Tuple(..) => {
-                Variant::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
-            }
+            // Important note here: `Variant::Tuple` is used on tuple structs which are not in an
+            // enum (so where converting from `ty::VariantDef`). In case we are in an enum, the kind
+            // is provided by the `Variant` wrapper directly, and since we need the fields' name
+            // (even for a tuple struct variant!), it's simpler to just store it as a
+            // `Variant::Struct` instead of a `Variant::Tuple` (otherwise it would force us to make
+            // a lot of changes when rendering them to generate the name as well).
+            hir::VariantData::Tuple(..) => Variant::Struct(self.clean(cx)),
             hir::VariantData::Unit(..) => Variant::CLike,
         }
     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 2b7f7aa3691bd..c05ea81ac1f36 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2007,6 +2007,9 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
             }
 
             sidebar.push_str("</div>");
+        } else if let CtorKind::Fn = s.struct_type {
+            sidebar
+                .push_str("<h3 class=\"sidebar-title\"><a href=\"#fields\">Tuple Fields</a></h3>");
         }
     }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 83ad4f7097bdf..5c30d8bbd173c 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1037,8 +1037,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                 write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
                 write!(
                     w,
-                    "<h3>Fields of <b>{name}</b></h3><div>",
-                    name = variant.name.as_ref().unwrap()
+                    "<h3>{extra}Fields of <b>{name}</b></h3><div>",
+                    extra = if s.struct_type == CtorKind::Fn { "Tuple " } else { "" },
+                    name = variant.name.as_ref().unwrap(),
                 );
                 for field in &s.fields {
                     use crate::clean::StructFieldItem;
@@ -1176,21 +1177,21 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
             _ => None,
         })
         .peekable();
-    if let CtorKind::Fictive = s.struct_type {
+    if let CtorKind::Fictive | CtorKind::Fn = s.struct_type {
         if fields.peek().is_some() {
             write!(
                 w,
                 "<h2 id=\"fields\" class=\"fields small-section-header\">\
-                       Fields{}<a href=\"#fields\" class=\"anchor\"></a></h2>",
+                     {}{}<a href=\"#fields\" class=\"anchor\"></a>\
+                 </h2>",
+                if let CtorKind::Fictive = s.struct_type { "Fields" } else { "Tuple Fields" },
                 document_non_exhaustive_header(it)
             );
             document_non_exhaustive(w, it);
-            for (field, ty) in fields {
-                let id = cx.derive_id(format!(
-                    "{}.{}",
-                    ItemType::StructField,
-                    field.name.as_ref().unwrap()
-                ));
+            for (index, (field, ty)) in fields.enumerate() {
+                let field_name =
+                    field.name.map_or_else(|| index.to_string(), |sym| (*sym.as_str()).to_string());
+                let id = cx.derive_id(format!("{}.{}", ItemType::StructField, field_name));
                 write!(
                     w,
                     "<span id=\"{id}\" class=\"{item_type} small-section-header\">\
@@ -1199,7 +1200,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
                      </span>",
                     item_type = ItemType::StructField,
                     id = id,
-                    name = field.name.as_ref().unwrap(),
+                    name = field_name,
                     ty = ty.print(cx)
                 );
                 document(w, cx, field, Some(it));
@@ -1507,7 +1508,10 @@ fn render_struct(
             if let Some(g) = g {
                 write!(w, "{}", print_where_clause(g, cx, 0, false),)
             }
-            w.write_str(";");
+            // We only want a ";" when we are displaying a tuple struct, not a variant tuple struct.
+            if structhead {
+                w.write_str(";");
+            }
         }
         CtorKind::Const => {
             // Needed for PhantomData.
diff --git a/src/test/rustdoc-ui/coverage/enums.stdout b/src/test/rustdoc-ui/coverage/enums.stdout
index 64c012c1f66e3..414d60c86d308 100644
--- a/src/test/rustdoc-ui/coverage/enums.stdout
+++ b/src/test/rustdoc-ui/coverage/enums.stdout
@@ -1,7 +1,7 @@
 +-------------------------------------+------------+------------+------------+------------+
 | File                                | Documented | Percentage |   Examples | Percentage |
 +-------------------------------------+------------+------------+------------+------------+
-| ...est/rustdoc-ui/coverage/enums.rs |          6 |      75.0% |          0 |       0.0% |
+| ...est/rustdoc-ui/coverage/enums.rs |          6 |      66.7% |          0 |       0.0% |
 +-------------------------------------+------------+------------+------------+------------+
-| Total                               |          6 |      75.0% |          0 |       0.0% |
+| Total                               |          6 |      66.7% |          0 |       0.0% |
 +-------------------------------------+------------+------------+------------+------------+
diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs
index 8d2046591d08a..ae871e79d7f6b 100644
--- a/src/test/rustdoc/toggle-item-contents.rs
+++ b/src/test/rustdoc/toggle-item-contents.rs
@@ -81,8 +81,8 @@ pub enum EnumStructVariant {
 }
 
 // @has 'toggle_item_contents/enum.LargeEnum.html'
-// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
+// @count - '//*[@class="rust enum"]//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//*[@class="rust enum"]//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
 pub enum LargeEnum {
     A, B, C, D, E, F(u8), G, H, I, J, K, L, M
 }
diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs
new file mode 100644
index 0000000000000..f3d8e39ea2d26
--- /dev/null
+++ b/src/test/rustdoc/tuple-struct-fields-doc.rs
@@ -0,0 +1,36 @@
+#![crate_name = "foo"]
+
+// @has foo/struct.Foo.html
+// @has - '//h2[@id="fields"]' 'Tuple Fields'
+// @has - '//h3[@class="sidebar-title"]/a[@href="#fields"]' 'Tuple Fields'
+// @has - '//*[@id="structfield.0"]' '0: u32'
+// @has - '//*[@id="main"]/div[@class="docblock"]' 'hello'
+// @!has - '//*[@id="structfield.1"]'
+// @has - '//*[@id="structfield.2"]' '2: char'
+// @has - '//*[@id="structfield.3"]' '3: i8'
+// @has - '//*[@id="main"]/div[@class="docblock"]' 'not hello'
+pub struct Foo(
+    /// hello
+    pub u32,
+    char,
+    pub char,
+    /// not hello
+    pub i8,
+);
+
+// @has foo/enum.Bar.html
+// @has - '//pre[@class="rust enum"]' 'BarVariant(String),'
+// @matches - '//*[@id="variant.BarVariant.fields"]/h3' '^Tuple Fields of BarVariant$'
+// @has - '//*[@id="variant.BarVariant.field.0"]' '0: String'
+// @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs'
+// @matches - '//*[@id="variant.FooVariant.fields"]/h3' '^Fields of FooVariant$'
+pub enum Bar {
+    BarVariant(
+        /// Hello docs
+        String
+    ),
+    FooVariant {
+       /// hello
+       x: u32,
+    },
+}
diff --git a/src/test/ui-fulldeps/plugin-args.stderr b/src/test/ui-fulldeps/plugin-args.stderr
index 2e255f185e291..177f33005c8cb 100644
--- a/src/test/ui-fulldeps/plugin-args.stderr
+++ b/src/test/ui-fulldeps/plugin-args.stderr
@@ -14,3 +14,4 @@ LL | #![plugin(empty_plugin(args))]
 
 error: aborting due to previous error; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0498`.
diff --git a/src/test/ui/bastion-of-the-turbofish.rs b/src/test/ui/bastion-of-the-turbofish.rs
index 233ddbbe11784..e12857008a5e0 100644
--- a/src/test/ui/bastion-of-the-turbofish.rs
+++ b/src/test/ui/bastion-of-the-turbofish.rs
@@ -20,13 +20,17 @@
 // in permitting generic arguments to be provided without the consent of the
 // Great Turbofish. Should you be so naïve as to try to revolt against its
 // mighty clutches, here shall its wrath be indomitably displayed. This
-// program must pass for all eternity, fundamentally at odds with an impetuous
-// rebellion against the Turbofish.
+// program must pass for all eternity: forever watched by the guardian angel
+// which gave this beast its name, and stands fundamentally at odds with the
+// impetuous rebellion against the Turbofish.
 //
 // My heart aches in sorrow, for I know I am defeated. Let this be a warning
-// to all those who come after. Here stands the bastion of the Turbofish.
+// to all those who come after: for they too must overcome the impassible
+// hurdle of defeating the great beast, championed by a resolute winged
+// guardian.
 //
-// RIP Anna Harren, Guardian Angel of the Hallowed Turbofish. <3
+// Here stands the Bastion of the Turbofish, a memorial to Anna Harren,
+// Guardian Angel of these Hallowed Grounds. <3
 
 // See https://github.com/rust-lang/rust/pull/53562
 // and https://github.com/rust-lang/rfcs/pull/2527
@@ -34,6 +38,6 @@
 // for context.
 
 fn main() {
-    let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
-    let _: (bool, bool) = (oh<woe, is>(me));
+    let (the, guardian, stands, resolute) = ("the", "Turbofish", "remains", "undefeated");
+    let _: (bool, bool) = (the<guardian, stands>(resolute));
 }
diff --git a/src/test/ui/malformed/malformed-plugin-3.stderr b/src/test/ui/malformed/malformed-plugin-3.stderr
index 11abdb16e0b4e..64cb429ea745b 100644
--- a/src/test/ui/malformed/malformed-plugin-3.stderr
+++ b/src/test/ui/malformed/malformed-plugin-3.stderr
@@ -14,3 +14,4 @@ LL | #![plugin(foo="bleh")]
 
 error: aborting due to previous error; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0498`.