about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-07 15:32:19 +0000
committerbors <bors@rust-lang.org>2022-02-07 15:32:19 +0000
commitf52c31840df7ec9c9350baff51a8964b20b5e1ba (patch)
treea7ea66705f0f42dc17756f1a63b91f3faa2a5139
parentc5e414843ebfe25674d8e18a5369d6249fdee741 (diff)
parenta6c48108ad2a5bbfb161818a047e4497dde0afea (diff)
downloadrust-f52c31840df7ec9c9350baff51a8964b20b5e1ba.tar.gz
rust-f52c31840df7ec9c9350baff51a8964b20b5e1ba.zip
Auto merge of #93738 - m-ou-se:rollup-zjyd2et, r=m-ou-se
Rollup of 13 pull requests

Successful merges:

 - #88313 (Make the pre-commit script pre-push instead)
 - #91530 (Suggest 1-tuple parentheses on exprs without existing parens)
 - #92724 (Cleanup c_str.rs)
 - #93208 (Impl {Add,Sub,Mul,Div,Rem,BitXor,BitOr,BitAnd}Assign<$t> for Wrapping<$t> for rust 1.60.0)
 - #93394 (Don't allow {} to refer to implicit captures in format_args.)
 - #93416 (remove `allow_fail` test flag)
 - #93487 (Fix linking stage1 toolchain in `./x.py setup`)
 - #93673 (Linkify sidebar headings for sibling items)
 - #93680 (Drop json::from_reader)
 - #93682 (Update tracking issue for `const_fn_trait_bound`)
 - #93722 (Use shallow clones for submodules managed by rustbuild, not just bootstrap.py)
 - #93723 (Rerun bootstrap's build script when RUSTC changes)
 - #93737 (bootstrap: prefer using '--config' over 'RUST_BOOTSTRAP_CONFIG')

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs35
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs9
-rw-r--r--compiler/rustc_feature/src/active.rs4
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_feature/src/removed.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs50
-rw-r--r--compiler/rustc_serialize/src/json.rs22
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--library/core/src/num/wrapping.rs80
-rw-r--r--library/std/src/ffi/c_str.rs15
-rw-r--r--library/test/src/console.rs6
-rw-r--r--library/test/src/formatters/json.rs13
-rw-r--r--library/test/src/formatters/junit.rs2
-rw-r--r--library/test/src/formatters/pretty.rs25
-rw-r--r--library/test/src/formatters/terse.rs25
-rw-r--r--library/test/src/test_result.rs13
-rw-r--r--library/test/src/tests.rs58
-rw-r--r--library/test/src/types.rs6
-rw-r--r--src/bootstrap/bin/main.rs14
-rw-r--r--src/bootstrap/bootstrap.py4
-rw-r--r--src/bootstrap/build.rs2
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/bootstrap/setup.rs53
-rwxr-xr-xsrc/etc/pre-push.sh (renamed from src/etc/pre-commit.sh)2
-rw-r--r--src/librustdoc/doctest.rs3
-rw-r--r--src/librustdoc/html/markdown.rs12
-rw-r--r--src/librustdoc/html/markdown/tests.rs1
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css3
-rw-r--r--src/librustdoc/html/static/js/main.js40
-rw-r--r--src/test/run-make-fulldeps/libtest-json/output-default.json2
-rw-r--r--src/test/run-make-fulldeps/libtest-json/output-stdout-success.json2
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile.goml2
-rw-r--r--src/test/rustdoc-gui/sidebar.goml7
-rw-r--r--src/test/rustdoc-ui/check-attr-test.rs7
-rw-r--r--src/test/rustdoc-ui/check-attr-test.stderr60
-rw-r--r--src/test/rustdoc-ui/check-attr.rs10
-rw-r--r--src/test/rustdoc-ui/check-attr.stderr50
-rw-r--r--src/test/ui/consts/const-tup-index-span.stderr4
-rw-r--r--src/test/ui/consts/const_fn_trait_bound.stock.stderr6
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr24
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-allow_fail.rs8
-rw-r--r--src/test/ui/feature-gates/feature-gate-allow_fail.stderr12
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-93378.rs11
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-93378.stderr22
-rw-r--r--src/test/ui/fmt/format-args-capture.rs8
-rw-r--r--src/test/ui/nll/issue-55825-const-fn.stderr2
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.rs6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.stderr25
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.fixed6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.rs6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.stderr43
-rw-r--r--src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr6
-rw-r--r--src/test/ui/test-attrs/test-allow-fail-attr.rs17
-rw-r--r--src/tools/compiletest/src/header.rs3
55 files changed, 470 insertions, 389 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index aaa6580acc6..584fbd1b605 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -25,6 +25,7 @@ enum ArgumentType {
 
 enum Position {
     Exact(usize),
+    Capture(usize),
     Named(Symbol),
 }
 
@@ -49,6 +50,8 @@ struct Context<'a, 'b> {
     /// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
     /// * `names` (in JSON): `{"foo": 2}`
     args: Vec<P<ast::Expr>>,
+    /// The number of arguments that were added by implicit capturing.
+    num_captured_args: usize,
     /// Placeholder slot numbers indexed by argument.
     arg_types: Vec<Vec<usize>>,
     /// Unique format specs seen for each argument.
@@ -231,6 +234,11 @@ fn parse_args<'a>(
 }
 
 impl<'a, 'b> Context<'a, 'b> {
+    /// The number of arguments that were explicitly given.
+    fn num_args(&self) -> usize {
+        self.args.len() - self.num_captured_args
+    }
+
     fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
         // NOTE: the `unwrap_or` branch is needed in case of invalid format
         // arguments, e.g., `format_args!("{foo}")`.
@@ -345,7 +353,7 @@ impl<'a, 'b> Context<'a, 'b> {
     }
 
     fn describe_num_args(&self) -> Cow<'_, str> {
-        match self.args.len() {
+        match self.num_args() {
             0 => "no arguments were given".into(),
             1 => "there is 1 argument".into(),
             x => format!("there are {} arguments", x).into(),
@@ -371,7 +379,7 @@ impl<'a, 'b> Context<'a, 'b> {
 
         let count = self.pieces.len()
             + self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
-        if self.names.is_empty() && !numbered_position_args && count != self.args.len() {
+        if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
             e = self.ecx.struct_span_err(
                 sp,
                 &format!(
@@ -419,7 +427,7 @@ impl<'a, 'b> Context<'a, 'b> {
             if let Some(span) = fmt.precision_span {
                 let span = self.fmtsp.from_inner(span);
                 match fmt.precision {
-                    parse::CountIsParam(pos) if pos > self.args.len() => {
+                    parse::CountIsParam(pos) if pos > self.num_args() => {
                         e.span_label(
                             span,
                             &format!(
@@ -462,7 +470,7 @@ impl<'a, 'b> Context<'a, 'b> {
             if let Some(span) = fmt.width_span {
                 let span = self.fmtsp.from_inner(span);
                 match fmt.width {
-                    parse::CountIsParam(pos) if pos > self.args.len() => {
+                    parse::CountIsParam(pos) if pos > self.num_args() => {
                         e.span_label(
                             span,
                             &format!(
@@ -494,12 +502,15 @@ impl<'a, 'b> Context<'a, 'b> {
     /// Actually verifies and tracks a given format placeholder
     /// (a.k.a. argument).
     fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
+        if let Exact(arg) = arg {
+            if arg >= self.num_args() {
+                self.invalid_refs.push((arg, self.curpiece));
+                return;
+            }
+        }
+
         match arg {
-            Exact(arg) => {
-                if self.args.len() <= arg {
-                    self.invalid_refs.push((arg, self.curpiece));
-                    return;
-                }
+            Exact(arg) | Capture(arg) => {
                 match ty {
                     Placeholder(_) => {
                         // record every (position, type) combination only once
@@ -526,7 +537,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 match self.names.get(&name) {
                     Some(&idx) => {
                         // Treat as positional arg.
-                        self.verify_arg_type(Exact(idx), ty)
+                        self.verify_arg_type(Capture(idx), ty)
                     }
                     None => {
                         // For the moment capturing variables from format strings expanded from macros is
@@ -541,9 +552,10 @@ impl<'a, 'b> Context<'a, 'b> {
                             } else {
                                 self.fmtsp
                             };
+                            self.num_captured_args += 1;
                             self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
                             self.names.insert(name, idx);
-                            self.verify_arg_type(Exact(idx), ty)
+                            self.verify_arg_type(Capture(idx), ty)
                         } else {
                             let msg = format!("there is no argument named `{}`", name);
                             let sp = if self.is_literal {
@@ -1051,6 +1063,7 @@ pub fn expand_preparsed_format_args(
     let mut cx = Context {
         ecx,
         args,
+        num_captured_args: 0,
         arg_types,
         arg_unique_types,
         names,
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index c08b141b557..9459bb7047f 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -252,11 +252,6 @@ pub fn expand_test_or_bench(
                                         "ignore",
                                         cx.expr_bool(sp, should_ignore(&cx.sess, &item)),
                                     ),
-                                    // allow_fail: true | false
-                                    field(
-                                        "allow_fail",
-                                        cx.expr_bool(sp, should_fail(&cx.sess, &item)),
-                                    ),
                                     // compile_fail: true | false
                                     field("compile_fail", cx.expr_bool(sp, false)),
                                     // no_run: true | false
@@ -359,10 +354,6 @@ fn should_ignore(sess: &Session, i: &ast::Item) -> bool {
     sess.contains_name(&i.attrs, sym::ignore)
 }
 
-fn should_fail(sess: &Session, i: &ast::Item) -> bool {
-    sess.contains_name(&i.attrs, sym::allow_fail)
-}
-
 fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
     match cx.sess.find_by_name(&i.attrs, sym::should_panic) {
         Some(attr) => {
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index bfe2459dc8d..e5232bf3dd0 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -277,8 +277,6 @@ declare_features! (
     (incomplete, adt_const_params, "1.56.0", Some(44580), None),
     /// Allows defining an `#[alloc_error_handler]`.
     (active, alloc_error_handler, "1.29.0", Some(51540), None),
-    /// Allows a test to fail without failing the whole suite.
-    (active, allow_fail, "1.19.0", Some(46488), None),
     /// Allows explicit discriminants on non-unit enum variants.
     (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
     /// Allows trait methods with arbitrary self types.
@@ -332,7 +330,7 @@ declare_features! (
     /// Allows using and casting function pointers in a `const fn`.
     (active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
     /// Allows trait bounds in `const fn`.
-    (active, const_fn_trait_bound, "1.53.0", Some(57563), None),
+    (active, const_fn_trait_bound, "1.53.0", Some(93706), None),
     /// Allows `for _ in _` loops in const contexts.
     (active, const_for, "1.56.0", Some(87575), None),
     /// Allows argument and return position `impl Trait` in a `const fn`.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 3933746c319..cb2562d09a5 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -403,7 +403,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     },
 
     // Testing:
-    gated!(allow_fail, Normal, template!(Word), WarnFollowing, experimental!(allow_fail)),
     gated!(
         test_runner, CrateLevel, template!(List: "path"), ErrorFollowing, custom_test_frameworks,
         "custom test frameworks are an unstable feature",
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index b9f3b5ad1b1..f5f944db5e9 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -48,6 +48,8 @@ declare_features! (
     (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
      Some("merged into `#![feature(slice_patterns)]`")),
     (removed, allocator, "1.0.0", None, None, None),
+    /// Allows a test to fail without failing the whole suite.
+    (removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")),
     (removed, await_macro, "1.38.0", Some(50547), None,
      Some("subsumed by `.await` syntax")),
     /// Allows comparing raw pointers during const eval.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 1eb8190bd7d..c5da9977db7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2044,19 +2044,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         // If a tuple of length one was expected and the found expression has
                         // parentheses around it, perhaps the user meant to write `(expr,)` to
                         // build a tuple (issue #86100)
-                        (ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
-                            if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
-                                if let Some(code) =
-                                    code.strip_prefix('(').and_then(|s| s.strip_suffix(')'))
-                                {
-                                    err.span_suggestion(
-                                        span,
-                                        "use a trailing comma to create a tuple with one element",
-                                        format!("({},)", code),
-                                        Applicability::MaybeIncorrect,
-                                    );
-                                }
-                            }
+                        (ty::Tuple(_), _) => {
+                            self.emit_tuple_wrap_err(&mut err, span, found, expected)
                         }
                         // If a character was expected and the found expression is a string literal
                         // containing a single character, perhaps the user meant to write `'c'` to
@@ -2119,6 +2108,41 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         diag
     }
 
+    fn emit_tuple_wrap_err(
+        &self,
+        err: &mut DiagnosticBuilder<'tcx>,
+        span: Span,
+        found: Ty<'tcx>,
+        expected: Ty<'tcx>,
+    ) {
+        let [expected_tup_elem] = &expected.tuple_fields().collect::<Vec<_>>()[..]
+            else { return };
+
+        if !same_type_modulo_infer(expected_tup_elem, found) {
+            return;
+        }
+
+        let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
+            else { return };
+
+        let msg = "use a trailing comma to create a tuple with one element";
+        if code.starts_with('(') && code.ends_with(')') {
+            let before_close = span.hi() - BytePos::from_u32(1);
+            err.span_suggestion(
+                span.with_hi(before_close).shrink_to_hi(),
+                msg,
+                ",".into(),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            err.multipart_suggestion(
+                msg,
+                vec![(span.shrink_to_lo(), "(".into()), (span.shrink_to_hi(), ",)".into())],
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
     fn values_str(
         &self,
         values: ValuePairs<'tcx>,
diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs
index 044de8e4e24..6a398549241 100644
--- a/compiler/rustc_serialize/src/json.rs
+++ b/compiler/rustc_serialize/src/json.rs
@@ -185,8 +185,6 @@ use self::ParserState::*;
 
 use std::borrow::Cow;
 use std::collections::{BTreeMap, HashMap};
-use std::io;
-use std::io::prelude::*;
 use std::mem::swap;
 use std::num::FpCategory as Fp;
 use std::ops::Index;
@@ -250,7 +248,6 @@ pub enum ErrorCode {
 pub enum ParserError {
     /// msg, line, col
     SyntaxError(ErrorCode, usize, usize),
-    IoError(io::ErrorKind, String),
 }
 
 // Builder and Parser have the same errors.
@@ -329,10 +326,6 @@ impl fmt::Display for ErrorCode {
     }
 }
 
-fn io_error_to_error(io: io::Error) -> ParserError {
-    IoError(io.kind(), io.to_string())
-}
-
 impl fmt::Display for ParserError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // FIXME this should be a nicer error
@@ -2163,21 +2156,6 @@ impl<T: Iterator<Item = char>> Builder<T> {
     }
 }
 
-/// Decodes a json value from an `&mut io::Read`
-pub fn from_reader(rdr: &mut dyn Read) -> Result<Json, BuilderError> {
-    let mut contents = Vec::new();
-    match rdr.read_to_end(&mut contents) {
-        Ok(c) => c,
-        Err(e) => return Err(io_error_to_error(e)),
-    };
-    let s = match str::from_utf8(&contents).ok() {
-        Some(s) => s,
-        _ => return Err(SyntaxError(NotUtf8, 0, 0)),
-    };
-    let mut builder = Builder::new(s.chars());
-    builder.build()
-}
-
 /// Decodes a json value from a string
 pub fn from_str(s: &str) -> Result<Json, BuilderError> {
     let mut builder = Builder::new(s.chars());
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 92ee3fd294b..c96c52752d0 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2148,8 +2148,8 @@ impl Target {
         use std::fs;
 
         fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
-            let contents = fs::read(path).map_err(|e| e.to_string())?;
-            let obj = json::from_reader(&mut &contents[..]).map_err(|e| e.to_string())?;
+            let contents = fs::read_to_string(path).map_err(|e| e.to_string())?;
+            let obj = json::from_str(&contents).map_err(|e| e.to_string())?;
             Target::from_json(obj)
         }
 
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index a0e42c51e45..5353d900e76 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -239,6 +239,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const AddAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn add_assign(&mut self, other: $t) {
+                *self = *self + Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const Sub for Wrapping<$t> {
@@ -262,6 +272,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const SubAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn sub_assign(&mut self, other: $t) {
+                *self = *self - Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const Mul for Wrapping<$t> {
@@ -285,6 +305,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const MulAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn mul_assign(&mut self, other: $t) {
+                *self = *self * Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "wrapping_div", since = "1.3.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const Div for Wrapping<$t> {
@@ -308,6 +338,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const DivAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn div_assign(&mut self, other: $t) {
+                *self = *self / Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "wrapping_impls", since = "1.7.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const Rem for Wrapping<$t> {
@@ -331,6 +371,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const RemAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn rem_assign(&mut self, other: $t) {
+                *self = *self % Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const Not for Wrapping<$t> {
@@ -367,6 +417,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const BitXorAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn bitxor_assign(&mut self, other: $t) {
+                *self = *self ^ Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const BitOr for Wrapping<$t> {
@@ -390,6 +450,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const BitOrAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn bitor_assign(&mut self, other: $t) {
+                *self = *self | Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const BitAnd for Wrapping<$t> {
@@ -413,6 +483,16 @@ macro_rules! wrapping_impl {
         }
         forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> }
 
+        #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const BitAndAssign<$t> for Wrapping<$t> {
+            #[inline]
+            fn bitand_assign(&mut self, other: $t) {
+                *self = *self & Wrapping(other);
+            }
+        }
+        forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t }
+
         #[stable(feature = "wrapping_neg", since = "1.10.0")]
         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
         impl const Neg for Wrapping<$t> {
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 66fee2fe548..e10c6a5daf1 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -1252,15 +1252,16 @@ impl CStr {
     /// assert!(cstr.is_err());
     /// ```
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> {
+    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
         let nul_pos = memchr::memchr(0, bytes);
-        if let Some(nul_pos) = nul_pos {
-            if nul_pos + 1 != bytes.len() {
-                return Err(FromBytesWithNulError::interior_nul(nul_pos));
+        match nul_pos {
+            Some(nul_pos) if nul_pos + 1 == bytes.len() => {
+                // SAFETY: We know there is only one nul byte, at the end
+                // of the byte slice.
+                Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
             }
-            Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) })
-        } else {
-            Err(FromBytesWithNulError::not_nul_terminated())
+            Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
+            None => Err(FromBytesWithNulError::not_nul_terminated()),
         }
     }
 
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index 9c261e8cc8e..920f55ad251 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -47,7 +47,6 @@ pub struct ConsoleTestState {
     pub passed: usize,
     pub failed: usize,
     pub ignored: usize,
-    pub allowed_fail: usize,
     pub filtered_out: usize,
     pub measured: usize,
     pub exec_time: Option<TestSuiteExecTime>,
@@ -71,7 +70,6 @@ impl ConsoleTestState {
             passed: 0,
             failed: 0,
             ignored: 0,
-            allowed_fail: 0,
             filtered_out: 0,
             measured: 0,
             exec_time: None,
@@ -112,7 +110,6 @@ impl ConsoleTestState {
                     TestResult::TrFailed => "failed".to_owned(),
                     TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
                     TestResult::TrIgnored => "ignored".to_owned(),
-                    TestResult::TrAllowedFail => "failed (allowed)".to_owned(),
                     TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
                     TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
                 },
@@ -126,7 +123,7 @@ impl ConsoleTestState {
     }
 
     fn current_test_count(&self) -> usize {
-        self.passed + self.failed + self.ignored + self.measured + self.allowed_fail
+        self.passed + self.failed + self.ignored + self.measured
     }
 }
 
@@ -191,7 +188,6 @@ fn handle_test_result(st: &mut ConsoleTestState, completed_test: CompletedTest)
             st.not_failures.push((test, stdout));
         }
         TestResult::TrIgnored => st.ignored += 1,
-        TestResult::TrAllowedFail => st.allowed_fail += 1,
         TestResult::TrBench(bs) => {
             st.metrics.insert_metric(
                 test.name.as_slice(),
diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs
index 424d3ef7b41..c089bfc4791 100644
--- a/library/test/src/formatters/json.rs
+++ b/library/test/src/formatters/json.rs
@@ -124,15 +124,6 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
                 self.write_event("test", desc.name.as_slice(), "ignored", exec_time, stdout, None)
             }
 
-            TestResult::TrAllowedFail => self.write_event(
-                "test",
-                desc.name.as_slice(),
-                "allowed_failure",
-                exec_time,
-                stdout,
-                None,
-            ),
-
             TestResult::TrBench(ref bs) => {
                 let median = bs.ns_iter_summ.median as usize;
                 let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
@@ -172,14 +163,12 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
              \"event\": \"{}\", \
              \"passed\": {}, \
              \"failed\": {}, \
-             \"allowed_fail\": {}, \
              \"ignored\": {}, \
              \"measured\": {}, \
              \"filtered_out\": {}",
             if state.failed == 0 { "ok" } else { "failed" },
             state.passed,
-            state.failed + state.allowed_fail,
-            state.allowed_fail,
+            state.failed,
             state.ignored,
             state.measured,
             state.filtered_out,
diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs
index f940a9ff8f1..54e9860ab54 100644
--- a/library/test/src/formatters/junit.rs
+++ b/library/test/src/formatters/junit.rs
@@ -121,7 +121,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                     ))?;
                 }
 
-                TestResult::TrOk | TestResult::TrAllowedFail => {
+                TestResult::TrOk => {
                     self.write_message(&*format!(
                         "<testcase classname=\"{}\" \
                          name=\"{}\" time=\"{}\"/>",
diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs
index 4a03b4b9147..4726ae864df 100644
--- a/library/test/src/formatters/pretty.rs
+++ b/library/test/src/formatters/pretty.rs
@@ -49,10 +49,6 @@ impl<T: Write> PrettyFormatter<T> {
         self.write_short_result("ignored", term::color::YELLOW)
     }
 
-    pub fn write_allowed_fail(&mut self) -> io::Result<()> {
-        self.write_short_result("FAILED (allowed)", term::color::YELLOW)
-    }
-
     pub fn write_time_failed(&mut self) -> io::Result<()> {
         self.write_short_result("FAILED (time limit exceeded)", term::color::RED)
     }
@@ -219,7 +215,6 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
             TestResult::TrOk => self.write_ok()?,
             TestResult::TrFailed | TestResult::TrFailedMsg(_) => self.write_failed()?,
             TestResult::TrIgnored => self.write_ignored()?,
-            TestResult::TrAllowedFail => self.write_allowed_fail()?,
             TestResult::TrBench(ref bs) => {
                 self.write_bench()?;
                 self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?;
@@ -263,22 +258,10 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
             self.write_pretty("FAILED", term::color::RED)?;
         }
 
-        let s = if state.allowed_fail > 0 {
-            format!(
-                ". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out",
-                state.passed,
-                state.failed + state.allowed_fail,
-                state.allowed_fail,
-                state.ignored,
-                state.measured,
-                state.filtered_out
-            )
-        } else {
-            format!(
-                ". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
-                state.passed, state.failed, state.ignored, state.measured, state.filtered_out
-            )
-        };
+        let s = format!(
+            ". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
+            state.passed, state.failed, state.ignored, state.measured, state.filtered_out
+        );
 
         self.write_plain(&s)?;
 
diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs
index 1f2c410cd96..12aca7cd9a4 100644
--- a/library/test/src/formatters/terse.rs
+++ b/library/test/src/formatters/terse.rs
@@ -54,10 +54,6 @@ impl<T: Write> TerseFormatter<T> {
         self.write_short_result("i", term::color::YELLOW)
     }
 
-    pub fn write_allowed_fail(&mut self) -> io::Result<()> {
-        self.write_short_result("a", term::color::YELLOW)
-    }
-
     pub fn write_bench(&mut self) -> io::Result<()> {
         self.write_pretty("bench", term::color::CYAN)
     }
@@ -207,7 +203,6 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
                 self.write_failed()
             }
             TestResult::TrIgnored => self.write_ignored(),
-            TestResult::TrAllowedFail => self.write_allowed_fail(),
             TestResult::TrBench(ref bs) => {
                 if self.is_multithreaded {
                     self.write_test_name(desc)?;
@@ -244,22 +239,10 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
             self.write_pretty("FAILED", term::color::RED)?;
         }
 
-        let s = if state.allowed_fail > 0 {
-            format!(
-                ". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out",
-                state.passed,
-                state.failed + state.allowed_fail,
-                state.allowed_fail,
-                state.ignored,
-                state.measured,
-                state.filtered_out
-            )
-        } else {
-            format!(
-                ". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
-                state.passed, state.failed, state.ignored, state.measured, state.filtered_out
-            )
-        };
+        let s = format!(
+            ". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
+            state.passed, state.failed, state.ignored, state.measured, state.filtered_out
+        );
 
         self.write_plain(&s)?;
 
diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs
index c5c56ca9c7f..8c216a1e0e7 100644
--- a/library/test/src/test_result.rs
+++ b/library/test/src/test_result.rs
@@ -19,7 +19,6 @@ pub enum TestResult {
     TrFailed,
     TrFailedMsg(String),
     TrIgnored,
-    TrAllowedFail,
     TrBench(BenchSamples),
     TrTimedFail,
 }
@@ -42,8 +41,6 @@ pub fn calc_result<'a>(
 
             if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) {
                 TestResult::TrOk
-            } else if desc.allow_fail {
-                TestResult::TrAllowedFail
             } else if let Some(panic_str) = maybe_panic_str {
                 TestResult::TrFailedMsg(format!(
                     r#"panic did not contain expected string
@@ -64,7 +61,6 @@ pub fn calc_result<'a>(
         (&ShouldPanic::Yes, Ok(())) | (&ShouldPanic::YesWithMessage(_), Ok(())) => {
             TestResult::TrFailedMsg("test did not panic as expected".to_string())
         }
-        _ if desc.allow_fail => TestResult::TrAllowedFail,
         _ => TestResult::TrFailed,
     };
 
@@ -90,11 +86,10 @@ pub fn get_result_from_exit_code(
     time_opts: &Option<time::TestTimeOptions>,
     exec_time: &Option<time::TestExecTime>,
 ) -> TestResult {
-    let result = match (desc.allow_fail, code) {
-        (_, TR_OK) => TestResult::TrOk,
-        (true, TR_FAILED) => TestResult::TrAllowedFail,
-        (false, TR_FAILED) => TestResult::TrFailed,
-        (_, _) => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
+    let result = match code {
+        TR_OK => TestResult::TrOk,
+        TR_FAILED => TestResult::TrFailed,
+        _ => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
     };
 
     // If test is already failed (or allowed to fail), do not change the result.
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 7f0b6193d09..9b9c5205686 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -62,10 +62,11 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
                 name: StaticTestName("1"),
                 ignore: true,
                 should_panic: ShouldPanic::No,
-                allow_fail: false,
                 compile_fail: false,
                 no_run: false,
                 test_type: TestType::Unknown,
+                #[cfg(bootstrap)]
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move || {})),
         },
@@ -74,10 +75,11 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
                 name: StaticTestName("2"),
                 ignore: false,
                 should_panic: ShouldPanic::No,
-                allow_fail: false,
                 compile_fail: false,
                 no_run: false,
                 test_type: TestType::Unknown,
+                #[cfg(bootstrap)]
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move || {})),
         },
@@ -94,10 +96,11 @@ pub fn do_not_run_ignored_tests() {
             name: StaticTestName("whatever"),
             ignore: true,
             should_panic: ShouldPanic::No,
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -115,10 +118,11 @@ pub fn ignored_tests_result_in_ignored() {
             name: StaticTestName("whatever"),
             ignore: true,
             should_panic: ShouldPanic::No,
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -140,10 +144,11 @@ fn test_should_panic() {
             name: StaticTestName("whatever"),
             ignore: false,
             should_panic: ShouldPanic::Yes,
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -165,10 +170,11 @@ fn test_should_panic_good_message() {
             name: StaticTestName("whatever"),
             ignore: false,
             should_panic: ShouldPanic::YesWithMessage("error message"),
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -195,10 +201,11 @@ fn test_should_panic_bad_message() {
             name: StaticTestName("whatever"),
             ignore: false,
             should_panic: ShouldPanic::YesWithMessage(expected),
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -229,10 +236,11 @@ fn test_should_panic_non_string_message_type() {
             name: StaticTestName("whatever"),
             ignore: false,
             should_panic: ShouldPanic::YesWithMessage(expected),
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -255,10 +263,11 @@ fn test_should_panic_but_succeeds() {
                 name: StaticTestName("whatever"),
                 ignore: false,
                 should_panic,
-                allow_fail: false,
                 compile_fail: false,
                 no_run: false,
                 test_type: TestType::Unknown,
+                #[cfg(bootstrap)]
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(f)),
         };
@@ -289,10 +298,11 @@ fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
             name: StaticTestName("whatever"),
             ignore: false,
             should_panic: ShouldPanic::No,
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -324,10 +334,11 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
             name: StaticTestName("whatever"),
             ignore: false,
             should_panic: ShouldPanic::No,
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(f)),
     };
@@ -363,10 +374,11 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
         name: StaticTestName("whatever"),
         ignore: false,
         should_panic: ShouldPanic::No,
-        allow_fail: false,
         compile_fail: false,
         no_run: false,
         test_type,
+        #[cfg(bootstrap)]
+        allow_fail: false,
     }
 }
 
@@ -476,10 +488,11 @@ pub fn exclude_should_panic_option() {
             name: StaticTestName("3"),
             ignore: false,
             should_panic: ShouldPanic::Yes,
-            allow_fail: false,
             compile_fail: false,
             no_run: false,
             test_type: TestType::Unknown,
+            #[cfg(bootstrap)]
+            allow_fail: false,
         },
         testfn: DynTestFn(Box::new(move || {})),
     });
@@ -500,10 +513,11 @@ pub fn exact_filter_match() {
                     name: StaticTestName(name),
                     ignore: false,
                     should_panic: ShouldPanic::No,
-                    allow_fail: false,
                     compile_fail: false,
                     no_run: false,
                     test_type: TestType::Unknown,
+                    #[cfg(bootstrap)]
+                    allow_fail: false,
                 },
                 testfn: DynTestFn(Box::new(move || {})),
             })
@@ -589,10 +603,11 @@ fn sample_tests() -> Vec<TestDescAndFn> {
                 name: DynTestName((*name).clone()),
                 ignore: false,
                 should_panic: ShouldPanic::No,
-                allow_fail: false,
                 compile_fail: false,
                 no_run: false,
                 test_type: TestType::Unknown,
+                #[cfg(bootstrap)]
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(testfn)),
         };
@@ -740,10 +755,11 @@ pub fn test_bench_no_iter() {
         name: StaticTestName("f"),
         ignore: false,
         should_panic: ShouldPanic::No,
-        allow_fail: false,
         compile_fail: false,
         no_run: false,
         test_type: TestType::Unknown,
+        #[cfg(bootstrap)]
+        allow_fail: false,
     };
 
     crate::bench::benchmark(TestId(0), desc, tx, true, f);
@@ -762,10 +778,11 @@ pub fn test_bench_iter() {
         name: StaticTestName("f"),
         ignore: false,
         should_panic: ShouldPanic::No,
-        allow_fail: false,
         compile_fail: false,
         no_run: false,
         test_type: TestType::Unknown,
+        #[cfg(bootstrap)]
+        allow_fail: false,
     };
 
     crate::bench::benchmark(TestId(0), desc, tx, true, f);
@@ -778,20 +795,22 @@ fn should_sort_failures_before_printing_them() {
         name: StaticTestName("a"),
         ignore: false,
         should_panic: ShouldPanic::No,
-        allow_fail: false,
         compile_fail: false,
         no_run: false,
         test_type: TestType::Unknown,
+        #[cfg(bootstrap)]
+        allow_fail: false,
     };
 
     let test_b = TestDesc {
         name: StaticTestName("b"),
         ignore: false,
         should_panic: ShouldPanic::No,
-        allow_fail: false,
         compile_fail: false,
         no_run: false,
         test_type: TestType::Unknown,
+        #[cfg(bootstrap)]
+        allow_fail: false,
     };
 
     let mut out = PrettyFormatter::new(OutputLocation::Raw(Vec::new()), false, 10, false, None);
@@ -802,7 +821,6 @@ fn should_sort_failures_before_printing_them() {
         passed: 0,
         failed: 0,
         ignored: 0,
-        allowed_fail: 0,
         filtered_out: 0,
         measured: 0,
         exec_time: None,
diff --git a/library/test/src/types.rs b/library/test/src/types.rs
index 37bb38fb0df..43e5a10ebbe 100644
--- a/library/test/src/types.rs
+++ b/library/test/src/types.rs
@@ -118,10 +118,11 @@ pub struct TestDesc {
     pub name: TestName,
     pub ignore: bool,
     pub should_panic: options::ShouldPanic,
-    pub allow_fail: bool,
     pub compile_fail: bool,
     pub no_run: bool,
     pub test_type: TestType,
+    #[cfg(bootstrap)]
+    pub allow_fail: bool,
 }
 
 impl TestDesc {
@@ -150,9 +151,6 @@ impl TestDesc {
             }
             options::ShouldPanic::No => {}
         }
-        if self.allow_fail {
-            return Some("allow fail");
-        }
         if self.compile_fail {
             return Some("compile fail");
         }
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index e730a2557e0..9c41ab69c8b 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -30,6 +30,7 @@ fn main() {
         println!("{}", suggestion);
     }
 
+    let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
     Build::new(config).build();
 
     if suggest_setup {
@@ -42,6 +43,19 @@ fn main() {
         println!("{}", suggestion);
     }
 
+    // Give a warning if the pre-commit script is in pre-commit and not pre-push.
+    // HACK: Since the commit script uses hard links, we can't actually tell if it was installed by x.py setup or not.
+    // We could see if it's identical to src/etc/pre-push.sh, but pre-push may have been modified in the meantime.
+    // Instead, look for this comment, which is almost certainly not in any custom hook.
+    if std::fs::read_to_string(pre_commit).map_or(false, |contents| {
+        contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
+    }) {
+        println!(
+            "warning: You have the pre-push script installed to .git/hooks/pre-commit. \
+                  Consider moving it to .git/hooks/pre-push instead, which runs less often."
+        );
+    }
+
     if suggest_setup || changelog_suggestion.is_some() {
         println!("note: this message was printed twice to make it more likely to be seen");
     }
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 6d7ab15326c..86115a90294 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1221,9 +1221,9 @@ def bootstrap(help_triggered):
     build.verbose = args.verbose
     build.clean = args.clean
 
-    # Read from `RUST_BOOTSTRAP_CONFIG`, then `--config`, then fallback to `config.toml` (if it
+    # Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then fallback to `config.toml` (if it
     # exists).
-    toml_path = os.getenv('RUST_BOOTSTRAP_CONFIG') or args.config
+    toml_path = args.config or os.getenv('RUST_BOOTSTRAP_CONFIG')
     if not toml_path and os.path.exists('config.toml'):
         toml_path = 'config.toml'
 
diff --git a/src/bootstrap/build.rs b/src/bootstrap/build.rs
index d40b924e0ff..6e39ea00f80 100644
--- a/src/bootstrap/build.rs
+++ b/src/bootstrap/build.rs
@@ -3,6 +3,8 @@ use std::path::PathBuf;
 
 fn main() {
     println!("cargo:rerun-if-changed=build.rs");
+    println!("cargo:rerun-if-env-changed=RUSTC");
+    println!("cargo:rerun-if-env-changed=PATH");
     println!("cargo:rustc-env=BUILD_TRIPLE={}", env::var("HOST").unwrap());
 
     // This may not be a canonicalized path.
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index e5f84d417bf..1a42d25c352 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -527,7 +527,7 @@ impl Build {
         // Try passing `--progress` to start, then run git again without if that fails.
         let update = |progress: bool| {
             let mut git = Command::new("git");
-            git.args(&["submodule", "update", "--init", "--recursive"]);
+            git.args(&["submodule", "update", "--init", "--recursive", "--depth=1"]);
             if progress {
                 git.arg("--progress");
             }
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index 5bc0a505bf6..9a9ef0b7695 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -1,7 +1,9 @@
 use crate::TargetSelection;
 use crate::{t, VERSION};
+use std::env::consts::EXE_SUFFIX;
 use std::fmt::Write as _;
-use std::path::{Path, PathBuf};
+use std::fs::File;
+use std::path::{Path, PathBuf, MAIN_SEPARATOR};
 use std::process::Command;
 use std::str::FromStr;
 use std::{
@@ -109,7 +111,8 @@ pub fn setup(src_path: &Path, profile: Profile) {
     println!("`x.py` will now use the configuration at {}", include_path.display());
 
     let build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
-    let stage_path = ["build", build.rustc_target_arg(), "stage1"].join("/");
+    let stage_path =
+        ["build", build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
 
     println!();
 
@@ -171,6 +174,13 @@ fn attempt_toolchain_link(stage_path: &str) {
         return;
     }
 
+    if !ensure_stage1_toolchain_placeholder_exists(stage_path) {
+        println!(
+            "Failed to create a template for stage 1 toolchain or confirm that it already exists"
+        );
+        return;
+    }
+
     if try_link_toolchain(&stage_path[..]) {
         println!(
             "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
@@ -219,6 +229,33 @@ fn try_link_toolchain(stage_path: &str) -> bool {
         .map_or(false, |output| output.status.success())
 }
 
+fn ensure_stage1_toolchain_placeholder_exists(stage_path: &str) -> bool {
+    let pathbuf = PathBuf::from(stage_path);
+
+    if fs::create_dir_all(pathbuf.join("lib")).is_err() {
+        return false;
+    };
+
+    let pathbuf = pathbuf.join("bin");
+    if fs::create_dir_all(&pathbuf).is_err() {
+        return false;
+    };
+
+    let pathbuf = pathbuf.join(format!("rustc{}", EXE_SUFFIX));
+
+    if pathbuf.exists() {
+        return true;
+    }
+
+    // Take care not to overwrite the file
+    let result = File::options().append(true).create(true).open(&pathbuf);
+    if result.is_err() {
+        return false;
+    }
+
+    return true;
+}
+
 // Used to get the path for `Subcommand::Setup`
 pub fn interactive_path() -> io::Result<Profile> {
     fn abbrev_all() -> impl Iterator<Item = ((String, String), Profile)> {
@@ -271,9 +308,9 @@ fn install_git_hook_maybe(src_path: &Path) -> io::Result<()> {
     let mut input = String::new();
     println!(
         "Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
-If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` on each commit
-to ensure your code is up to par. If you decide later that this behavior is undesirable,
-simply delete the `pre-commit` file from .git/hooks."
+If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` before
+pushing your code to ensure your code is up to par. If you decide later that this behavior is
+undesirable, simply delete the `pre-push` file from .git/hooks."
     );
 
     let should_install = loop {
@@ -293,21 +330,21 @@ simply delete the `pre-commit` file from .git/hooks."
     };
 
     if should_install {
-        let src = src_path.join("src").join("etc").join("pre-commit.sh");
+        let src = src_path.join("src").join("etc").join("pre-push.sh");
         let git = t!(Command::new("git").args(&["rev-parse", "--git-common-dir"]).output().map(
             |output| {
                 assert!(output.status.success(), "failed to run `git`");
                 PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
             }
         ));
-        let dst = git.join("hooks").join("pre-commit");
+        let dst = git.join("hooks").join("pre-push");
         match fs::hard_link(src, &dst) {
             Err(e) => println!(
                 "error: could not create hook {}: do you already have the git hook installed?\n{}",
                 dst.display(),
                 e
             ),
-            Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-commit`"),
+            Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-push`"),
         };
     } else {
         println!("Ok, skipping installation!");
diff --git a/src/etc/pre-commit.sh b/src/etc/pre-push.sh
index 9045adb54dc..a78725f2ab0 100755
--- a/src/etc/pre-commit.sh
+++ b/src/etc/pre-push.sh
@@ -16,7 +16,7 @@ if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
   COMMAND="python $COMMAND"
 fi
 
-echo "Running pre-commit script '$COMMAND'"
+echo "Running pre-push script '$COMMAND'"
 
 cd "$ROOT_DIR"
 
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index d16383723f5..6c55721c0dd 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -951,10 +951,11 @@ impl Tester for Collector {
                 },
                 // compiler failures are test failures
                 should_panic: test::ShouldPanic::No,
-                allow_fail: config.allow_fail,
                 compile_fail: config.compile_fail,
                 no_run,
                 test_type: test::TestType::DocTest,
+                #[cfg(bootstrap)]
+                allow_fail: false,
             },
             testfn: test::DynTestFn(box move || {
                 let report_unused_externs = |uext| {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index a9a3a0af276..a40181352f6 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -847,7 +847,6 @@ crate struct LangString {
     crate test_harness: bool,
     crate compile_fail: bool,
     crate error_codes: Vec<String>,
-    crate allow_fail: bool,
     crate edition: Option<Edition>,
 }
 
@@ -869,7 +868,6 @@ impl Default for LangString {
             test_harness: false,
             compile_fail: false,
             error_codes: Vec::new(),
-            allow_fail: false,
             edition: None,
         }
     }
@@ -943,10 +941,6 @@ impl LangString {
                         seen_rust_tags = !seen_other_tags;
                     }
                 }
-                "allow_fail" => {
-                    data.allow_fail = true;
-                    seen_rust_tags = !seen_other_tags;
-                }
                 "rust" => {
                     data.rust = true;
                     seen_rust_tags = true;
@@ -994,12 +988,6 @@ impl LangString {
                             "the code block will either not be tested if not marked as a rust one \
                              or will be run (which you might not want)",
                         ))
-                    } else if s == "allow-fail" || s == "allow_fail" || s == "allowfail" {
-                        Some((
-                            "allow_fail",
-                            "the code block will either not be tested if not marked as a rust one \
-                             or will be run (which you might not want)",
-                        ))
                     } else if s == "test-harness" || s == "test_harness" || s == "testharness" {
                         Some((
                             "test_harness",
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index d4af3663b62..ea6575d179d 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -70,7 +70,6 @@ fn test_lang_string_parse() {
         compile_fail: true,
         ..Default::default()
     });
-    t(LangString { original: "allow_fail".into(), allow_fail: true, ..Default::default() });
     t(LangString { original: "no_run,example".into(), no_run: true, ..Default::default() });
     t(LangString {
         original: "sh,should_panic".into(),
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 38ececf5e78..cf3c63d6a8f 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -472,6 +472,7 @@ nav.sub {
 }
 .block ul, .block li {
 	padding: 0;
+	margin: 0;
 	list-style: none;
 }
 
@@ -502,8 +503,6 @@ nav.sub {
 	font-weight: 500;
 	padding: 0;
 	margin: 0;
-	margin-top: 0.5rem;
-	margin-bottom: 0.25rem;
 }
 
 .sidebar-links,
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index cab3c28342d..8e1919f75d6 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -559,7 +559,15 @@ function hideThemeButtonState() {
             others.appendChild(div);
         }
 
-        function block(shortty, longty) {
+        /**
+         * Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
+         *
+         * @param {string} shortty - A short type name, like "primitive", "mod", or "macro"
+         * @param {string} id - The HTML id of the corresponding section on the module page.
+         * @param {string} longty - A long, capitalized, plural name, like "Primitive Types",
+         *                          "Modules", or "Macros".
+         */
+        function block(shortty, id, longty) {
             var filtered = items[shortty];
             if (!filtered) {
                 return;
@@ -568,7 +576,7 @@ function hideThemeButtonState() {
             var div = document.createElement("div");
             div.className = "block " + shortty;
             var h3 = document.createElement("h3");
-            h3.textContent = longty;
+            h3.innerHTML = `<a href="index.html#${id}">${longty}</a>`;
             div.appendChild(h3);
             var ul = document.createElement("ul");
 
@@ -607,20 +615,20 @@ function hideThemeButtonState() {
 
             var isModule = hasClass(document.body, "mod");
             if (!isModule) {
-                block("primitive", "Primitive Types");
-                block("mod", "Modules");
-                block("macro", "Macros");
-                block("struct", "Structs");
-                block("enum", "Enums");
-                block("union", "Unions");
-                block("constant", "Constants");
-                block("static", "Statics");
-                block("trait", "Traits");
-                block("fn", "Functions");
-                block("type", "Type Definitions");
-                block("foreigntype", "Foreign Types");
-                block("keyword", "Keywords");
-                block("traitalias", "Trait Aliases");
+                block("primitive", "primitives", "Primitive Types");
+                block("mod", "modules", "Modules");
+                block("macro", "macros", "Macros");
+                block("struct", "structs", "Structs");
+                block("enum", "enums", "Enums");
+                block("union", "unions", "Unions");
+                block("constant", "constants", "Constants");
+                block("static", "static", "Statics");
+                block("trait", "traits", "Traits");
+                block("fn", "functions", "Functions");
+                block("type", "types", "Type Definitions");
+                block("foreigntype", "foreign-types", "Foreign Types");
+                block("keyword", "keywords", "Keywords");
+                block("traitalias", "trait-aliases", "Trait Aliases");
             }
 
             // `crates{version}.js` should always be loaded before this script, so we can use
diff --git a/src/test/run-make-fulldeps/libtest-json/output-default.json b/src/test/run-make-fulldeps/libtest-json/output-default.json
index 099b65a23ca..e2c778aa865 100644
--- a/src/test/run-make-fulldeps/libtest-json/output-default.json
+++ b/src/test/run-make-fulldeps/libtest-json/output-default.json
@@ -7,4 +7,4 @@
 { "type": "test", "name": "c", "event": "ok" }
 { "type": "test", "event": "started", "name": "d" }
 { "type": "test", "name": "d", "event": "ignored" }
-{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
+{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
index fd676799a76..68eb00c297e 100644
--- a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
+++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
@@ -7,4 +7,4 @@
 { "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
 { "type": "test", "event": "started", "name": "d" }
 { "type": "test", "name": "d", "event": "ignored" }
-{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
+{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml
index 60bcffe120b..ef588a69f1d 100644
--- a/src/test/rustdoc-gui/sidebar-mobile.goml
+++ b/src/test/rustdoc-gui/sidebar-mobile.goml
@@ -39,4 +39,4 @@ assert-position: ("#method\.must_use", {"y": 45})
 // Check that the bottom-most item on the sidebar menu can be scrolled fully into view.
 click: ".sidebar-menu-toggle"
 scroll-to: ".block.keyword li:nth-child(1)"
-assert-position: (".block.keyword li:nth-child(1)", {"y": 542.96875})
+assert-position: (".block.keyword li:nth-child(1)", {"y": 542.234375})
diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml
index ef3a92ad7a6..9505e00512f 100644
--- a/src/test/rustdoc-gui/sidebar.goml
+++ b/src/test/rustdoc-gui/sidebar.goml
@@ -78,3 +78,10 @@ assert-text: ("#functions + .item-table .item-left > a", "foo")
 // Links to trait implementations in the sidebar should not wrap even if they are long.
 goto: file://|DOC_PATH|/lib2/struct.HasALongTraitWithParams.html
 assert-property: (".sidebar-links a", {"offsetHeight": 29})
+
+// Test that clicking on of the "In <module>" headings in the sidebar links to the
+// appropriate anchor in index.html.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+click: ".block.mod h3 a"
+// PAGE: index.html
+assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"})
diff --git a/src/test/rustdoc-ui/check-attr-test.rs b/src/test/rustdoc-ui/check-attr-test.rs
index 023d620bea2..e955470148a 100644
--- a/src/test/rustdoc-ui/check-attr-test.rs
+++ b/src/test/rustdoc-ui/check-attr-test.rs
@@ -23,13 +23,6 @@ pub fn bar() {}
 /// ```
 pub fn foobar() {}
 
-/// barfoo
-///
-/// ```allow-fail,allowfail,allOw_fail
-/// boo
-/// ```
-pub fn barfoo() {}
-
 /// b
 ///
 /// ```test-harness,testharness,tesT_harness
diff --git a/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr
index affd0372a1f..b1fa9edf0e4 100644
--- a/src/test/rustdoc-ui/check-attr-test.stderr
+++ b/src/test/rustdoc-ui/check-attr-test.stderr
@@ -111,77 +111,41 @@ error: unknown attribute `nO_run`. Did you mean `no_run`?
    |
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `allow-fail`. Did you mean `allow_fail`?
+error: unknown attribute `test-harness`. Did you mean `test_harness`?
   --> $DIR/check-attr-test.rs:26:1
    |
-26 | / /// barfoo
+26 | / /// b
 27 | | ///
-28 | | /// ```allow-fail,allowfail,allOw_fail
+28 | | /// ```test-harness,testharness,tesT_harness
 29 | | /// boo
 30 | | /// ```
    | |_______^
    |
-   = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
+   = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: unknown attribute `allowfail`. Did you mean `allow_fail`?
+error: unknown attribute `testharness`. Did you mean `test_harness`?
   --> $DIR/check-attr-test.rs:26:1
    |
-26 | / /// barfoo
+26 | / /// b
 27 | | ///
-28 | | /// ```allow-fail,allowfail,allOw_fail
+28 | | /// ```test-harness,testharness,tesT_harness
 29 | | /// boo
 30 | | /// ```
    | |_______^
    |
-   = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
+   = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: unknown attribute `allOw_fail`. Did you mean `allow_fail`?
+error: unknown attribute `tesT_harness`. Did you mean `test_harness`?
   --> $DIR/check-attr-test.rs:26:1
    |
-26 | / /// barfoo
+26 | / /// b
 27 | | ///
-28 | | /// ```allow-fail,allowfail,allOw_fail
+28 | | /// ```test-harness,testharness,tesT_harness
 29 | | /// boo
 30 | | /// ```
    | |_______^
    |
-   = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
-
-error: unknown attribute `test-harness`. Did you mean `test_harness`?
-  --> $DIR/check-attr-test.rs:33:1
-   |
-33 | / /// b
-34 | | ///
-35 | | /// ```test-harness,testharness,tesT_harness
-36 | | /// boo
-37 | | /// ```
-   | |_______^
-   |
-   = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
-
-error: unknown attribute `testharness`. Did you mean `test_harness`?
-  --> $DIR/check-attr-test.rs:33:1
-   |
-33 | / /// b
-34 | | ///
-35 | | /// ```test-harness,testharness,tesT_harness
-36 | | /// boo
-37 | | /// ```
-   | |_______^
-   |
-   = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
-
-error: unknown attribute `tesT_harness`. Did you mean `test_harness`?
-  --> $DIR/check-attr-test.rs:33:1
-   |
-33 | / /// b
-34 | | ///
-35 | | /// ```test-harness,testharness,tesT_harness
-36 | | /// boo
-37 | | /// ```
-   | |_______^
-   |
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: aborting due to 15 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/test/rustdoc-ui/check-attr.rs b/src/test/rustdoc-ui/check-attr.rs
index 763bc4c6cdd..0b3f7bedda5 100644
--- a/src/test/rustdoc-ui/check-attr.rs
+++ b/src/test/rustdoc-ui/check-attr.rs
@@ -30,16 +30,6 @@ pub fn bar() {}
 /// ```
 pub fn foobar() {}
 
-/// barfoo
-//~^ ERROR
-//~^^ ERROR
-//~^^^ ERROR
-///
-/// ```allow-fail,allowfail,alLow_fail
-/// boo
-/// ```
-pub fn barfoo() {}
-
 /// b
 //~^ ERROR
 //~^^ ERROR
diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr
index 9312cfb76f3..370b804c56c 100644
--- a/src/test/rustdoc-ui/check-attr.stderr
+++ b/src/test/rustdoc-ui/check-attr.stderr
@@ -129,50 +129,8 @@ LL | | /// ```
    |
    = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
 
-error: unknown attribute `allow-fail`. Did you mean `allow_fail`?
-  --> $DIR/check-attr.rs:33:1
-   |
-LL | / /// barfoo
-LL | |
-LL | |
-LL | |
-...  |
-LL | | /// boo
-LL | | /// ```
-   | |_______^
-   |
-   = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
-
-error: unknown attribute `allowfail`. Did you mean `allow_fail`?
-  --> $DIR/check-attr.rs:33:1
-   |
-LL | / /// barfoo
-LL | |
-LL | |
-LL | |
-...  |
-LL | | /// boo
-LL | | /// ```
-   | |_______^
-   |
-   = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
-
-error: unknown attribute `alLow_fail`. Did you mean `allow_fail`?
-  --> $DIR/check-attr.rs:33:1
-   |
-LL | / /// barfoo
-LL | |
-LL | |
-LL | |
-...  |
-LL | | /// boo
-LL | | /// ```
-   | |_______^
-   |
-   = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
-
 error: unknown attribute `test-harness`. Did you mean `test_harness`?
-  --> $DIR/check-attr.rs:43:1
+  --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
 LL | |
@@ -186,7 +144,7 @@ LL | | /// ```
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
-  --> $DIR/check-attr.rs:43:1
+  --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
 LL | |
@@ -200,7 +158,7 @@ LL | | /// ```
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
 error: unknown attribute `teSt_harness`. Did you mean `test_harness`?
-  --> $DIR/check-attr.rs:43:1
+  --> $DIR/check-attr.rs:33:1
    |
 LL | / /// b
 LL | |
@@ -213,5 +171,5 @@ LL | | /// ```
    |
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
-error: aborting due to 15 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr
index 6724984d8d7..d301f8c4054 100644
--- a/src/test/ui/consts/const-tup-index-span.stderr
+++ b/src/test/ui/consts/const-tup-index-span.stderr
@@ -6,6 +6,10 @@ LL | const TUP: (usize,) = 5usize << 64;
    |
    = note: expected tuple `(usize,)`
                found type `usize`
+help: use a trailing comma to create a tuple with one element
+   |
+LL | const TUP: (usize,) = (5usize << 64,);
+   |                       +            ++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const_fn_trait_bound.stock.stderr b/src/test/ui/consts/const_fn_trait_bound.stock.stderr
index d652b5268a8..7d9e18cb341 100644
--- a/src/test/ui/consts/const_fn_trait_bound.stock.stderr
+++ b/src/test/ui/consts/const_fn_trait_bound.stock.stderr
@@ -4,7 +4,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
 LL | const fn test1<T: std::ops::Add>() {}
    |                ^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -13,7 +13,7 @@ error[E0658]: trait objects in const fn are unstable
 LL | const fn test2(_x: &dyn Send) {}
    |                ^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -22,7 +22,7 @@ error[E0658]: trait objects in const fn are unstable
 LL | const fn test3() -> &'static dyn Send { loop {} }
    |                     ^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index fd1ab6f64bf..67cb604b6a7 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -136,7 +136,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
 LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
    |                ^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@@ -145,7 +145,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
 LL | const fn foo11_2<T: Send>(t: T) -> T { t }
    |                  ^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0013]: constant functions cannot refer to statics
@@ -218,7 +218,7 @@ LL |
 LL |     const fn foo(&self) {}
    |     ------------------- function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@@ -230,7 +230,7 @@ LL |
 LL |     const fn foo2(&self) {}
    |     -------------------- function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@@ -242,7 +242,7 @@ LL |
 LL |     const fn foo3(&self) {}
    |     -------------------- function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@@ -251,7 +251,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
 LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    |                                  ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0493]: destructors cannot be evaluated at compile-time
@@ -268,7 +268,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
 LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    |                      ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0493]: destructors cannot be evaluated at compile-time
@@ -285,7 +285,7 @@ error[E0658]: trait objects in const fn are unstable
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
    |                       ^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -294,7 +294,7 @@ error[E0658]: trait objects in const fn are unstable
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -305,7 +305,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    | |
    | function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -316,7 +316,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    | |
    | function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -327,7 +327,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    | |
    | function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: function pointers cannot appear in constant functions
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
index 6eec1df5aec..4c2199101d3 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
@@ -6,7 +6,7 @@ LL | const fn no_inner_dyn_trait2(x: Hide) {
 LL |     x.0.field;
    |     ^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: trait objects in const fn are unstable
@@ -17,7 +17,7 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
    | |
    | function declared as const here
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.rs b/src/test/ui/feature-gates/feature-gate-allow_fail.rs
deleted file mode 100644
index 287d4ccf180..00000000000
--- a/src/test/ui/feature-gates/feature-gate-allow_fail.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// check that #[allow_fail] is feature-gated
-
-#[allow_fail] //~ ERROR the `#[allow_fail]` attribute is an experimental feature
-fn ok_to_fail() {
-    assert!(false);
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
deleted file mode 100644
index 76115fb9698..00000000000
--- a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: the `#[allow_fail]` attribute is an experimental feature
-  --> $DIR/feature-gate-allow_fail.rs:3:1
-   |
-LL | #[allow_fail]
-   | ^^^^^^^^^^^^^
-   |
-   = note: see issue #46488 <https://github.com/rust-lang/rust/issues/46488> for more information
-   = help: add `#![feature(allow_fail)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.rs b/src/test/ui/fmt/format-args-capture-issue-93378.rs
new file mode 100644
index 00000000000..67444444264
--- /dev/null
+++ b/src/test/ui/fmt/format-args-capture-issue-93378.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let a = "a";
+    let b = "b";
+
+    println!("{a} {b} {} {} {c} {}", c = "c");
+    //~^ ERROR: invalid reference to positional arguments 1 and 2 (there is 1 argument)
+
+    let n = 1;
+    println!("{a:.n$} {b:.*}");
+    //~^ ERROR: invalid reference to positional argument 0 (no arguments were given)
+}
diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.stderr b/src/test/ui/fmt/format-args-capture-issue-93378.stderr
new file mode 100644
index 00000000000..588541044fe
--- /dev/null
+++ b/src/test/ui/fmt/format-args-capture-issue-93378.stderr
@@ -0,0 +1,22 @@
+error: invalid reference to positional arguments 1 and 2 (there is 1 argument)
+  --> $DIR/format-args-capture-issue-93378.rs:5:26
+   |
+LL |     println!("{a} {b} {} {} {c} {}", c = "c");
+   |                          ^^     ^^
+   |
+   = note: positional arguments are zero-based
+
+error: invalid reference to positional argument 0 (no arguments were given)
+  --> $DIR/format-args-capture-issue-93378.rs:9:23
+   |
+LL |     println!("{a:.n$} {b:.*}");
+   |               ------- ^^^--^
+   |               |          |
+   |               |          this precision flag adds an extra required argument at position 0, which is why there are 3 arguments expected
+   |               this parameter corresponds to the precision flag
+   |
+   = note: positional arguments are zero-based
+   = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs
index e830a5bc9c5..d31d2a6c336 100644
--- a/src/test/ui/fmt/format-args-capture.rs
+++ b/src/test/ui/fmt/format-args-capture.rs
@@ -5,6 +5,7 @@ fn main() {
     named_argument_takes_precedence_to_captured();
     formatting_parameters_can_be_captured();
     capture_raw_strings_and_idents();
+    repeated_capture();
 
     #[cfg(panic = "unwind")]
     {
@@ -80,3 +81,10 @@ fn formatting_parameters_can_be_captured() {
     let s = format!("{x:-^width$.precision$}");
     assert_eq!(&s, "--7.000--");
 }
+
+fn repeated_capture() {
+    let a = 1;
+    let b = 2;
+    let s = format!("{a} {b} {a}");
+    assert_eq!(&s, "1 2 1");
+}
diff --git a/src/test/ui/nll/issue-55825-const-fn.stderr b/src/test/ui/nll/issue-55825-const-fn.stderr
index 9af5180343b..c834f8bd9c4 100644
--- a/src/test/ui/nll/issue-55825-const-fn.stderr
+++ b/src/test/ui/nll/issue-55825-const-fn.stderr
@@ -4,7 +4,7 @@ error[E0658]: trait objects in const fn are unstable
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error: aborting due to previous error
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.rs b/src/test/ui/suggestions/args-instead-of-tuple-errors.rs
index 2c3ee5fcb80..5403b8d6d28 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.rs
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.rs
@@ -10,6 +10,12 @@ fn main() {
 
     let _: Option<(i8,)> = Some();
     //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
+
+    let _: Option<(i32,)> = Some(5_usize);
+    //~^ ERROR mismatched types
+
+    let _: Option<(i32,)> = Some((5_usize));
+    //~^ ERROR mismatched types
 }
 
 fn int_bool(_: (i32, bool)) {
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
index a2ad602dbd4..ddcdfb1c3b3 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -15,7 +15,7 @@ LL |     int_bool(1, 2);
    |     expected 1 argument
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple-errors.rs:15:4
+  --> $DIR/args-instead-of-tuple-errors.rs:21:4
    |
 LL | fn int_bool(_: (i32, bool)) {
    |    ^^^^^^^^ --------------
@@ -28,6 +28,25 @@ LL |     let _: Option<(i8,)> = Some();
    |                            |
    |                            expected 1 argument
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple-errors.rs:14:34
+   |
+LL |     let _: Option<(i32,)> = Some(5_usize);
+   |                                  ^^^^^^^ expected tuple, found `usize`
+   |
+   = note: expected tuple `(i32,)`
+               found type `usize`
+
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple-errors.rs:17:34
+   |
+LL |     let _: Option<(i32,)> = Some((5_usize));
+   |                                  ^^^^^^^^^ expected tuple, found `usize`
+   |
+   = note: expected tuple `(i32,)`
+               found type `usize`
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0061`.
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.fixed b/src/test/ui/suggestions/args-instead-of-tuple.fixed
index c9b8a41d469..66e53f9ce2c 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.fixed
+++ b/src/test/ui/suggestions/args-instead-of-tuple.fixed
@@ -11,6 +11,12 @@ fn main() {
     let _: Option<()> = Some(());
     //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
 
+    let _: Option<(i32,)> = Some((3,));
+    //~^ ERROR mismatched types
+
+    let _: Option<(i32,)> = Some((3,));
+    //~^ ERROR mismatched types
+
     two_ints((1, 2)); //~ ERROR this function takes 1 argument
 
     with_generic((3, 4)); //~ ERROR this function takes 1 argument
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.rs b/src/test/ui/suggestions/args-instead-of-tuple.rs
index d4cc3024dd0..a15bff07ebf 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.rs
+++ b/src/test/ui/suggestions/args-instead-of-tuple.rs
@@ -11,6 +11,12 @@ fn main() {
     let _: Option<()> = Some();
     //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
 
+    let _: Option<(i32,)> = Some(3);
+    //~^ ERROR mismatched types
+
+    let _: Option<(i32,)> = Some((3));
+    //~^ ERROR mismatched types
+
     two_ints(1, 2); //~ ERROR this function takes 1 argument
 
     with_generic(3, 4); //~ ERROR this function takes 1 argument
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.stderr b/src/test/ui/suggestions/args-instead-of-tuple.stderr
index 172db7ee3df..6a7602c9d0f 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple.stderr
@@ -31,14 +31,40 @@ help: expected the unit value `()`; create it with empty parentheses
 LL |     let _: Option<()> = Some(());
    |                              ++
 
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple.rs:14:34
+   |
+LL |     let _: Option<(i32,)> = Some(3);
+   |                                  ^ expected tuple, found integer
+   |
+   = note: expected tuple `(i32,)`
+               found type `{integer}`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     let _: Option<(i32,)> = Some((3,));
+   |                                  + ++
+
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple.rs:17:34
+   |
+LL |     let _: Option<(i32,)> = Some((3));
+   |                                  ^^^ expected tuple, found integer
+   |
+   = note: expected tuple `(i32,)`
+               found type `{integer}`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     let _: Option<(i32,)> = Some((3,));
+   |                                    +
+
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/args-instead-of-tuple.rs:14:5
+  --> $DIR/args-instead-of-tuple.rs:20:5
    |
 LL |     two_ints(1, 2);
    |     ^^^^^^^^ -  - supplied 2 arguments
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple.rs:19:4
+  --> $DIR/args-instead-of-tuple.rs:25:4
    |
 LL | fn two_ints(_: (i32, i32)) {
    |    ^^^^^^^^ -------------
@@ -48,13 +74,13 @@ LL |     two_ints((1, 2));
    |              +    +
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/args-instead-of-tuple.rs:16:5
+  --> $DIR/args-instead-of-tuple.rs:22:5
    |
 LL |     with_generic(3, 4);
    |     ^^^^^^^^^^^^ -  - supplied 2 arguments
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple.rs:22:4
+  --> $DIR/args-instead-of-tuple.rs:28:4
    |
 LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
    |    ^^^^^^^^^^^^                 ----------------
@@ -64,13 +90,13 @@ LL |     with_generic((3, 4));
    |                  +    +
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/args-instead-of-tuple.rs:25:9
+  --> $DIR/args-instead-of-tuple.rs:31:9
    |
 LL |         with_generic(a, b);
    |         ^^^^^^^^^^^^ -  - supplied 2 arguments
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple.rs:22:4
+  --> $DIR/args-instead-of-tuple.rs:28:4
    |
 LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
    |    ^^^^^^^^^^^^                 ----------------
@@ -79,6 +105,7 @@ help: use parentheses to construct a tuple
 LL |         with_generic((a, b));
    |                      +    +
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0061`.
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
index 9c8356a5284..0016f192842 100644
--- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
@@ -11,7 +11,7 @@ LL |     let _x: (i32,) = (5);
 help: use a trailing comma to create a tuple with one element
    |
 LL |     let _x: (i32,) = (5,);
-   |                      ~~~~
+   |                        +
 
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:13:9
@@ -24,7 +24,7 @@ LL |     foo((Some(3)));
 help: use a trailing comma to create a tuple with one element
    |
 LL |     foo((Some(3),));
-   |         ~~~~~~~~~~
+   |                 +
 
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:17:22
@@ -37,7 +37,7 @@ LL |     let _s = S { _s: ("abc".to_string()) };
 help: use a trailing comma to create a tuple with one element
    |
 LL |     let _s = S { _s: ("abc".to_string(),) };
-   |                      ~~~~~~~~~~~~~~~~~~~~
+   |                                        +
 
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:23:22
diff --git a/src/test/ui/test-attrs/test-allow-fail-attr.rs b/src/test/ui/test-attrs/test-allow-fail-attr.rs
deleted file mode 100644
index 29ce9f7c2e9..00000000000
--- a/src/test/ui/test-attrs/test-allow-fail-attr.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// run-pass
-// compile-flags: --test
-#![feature(allow_fail)]
-#![feature(cfg_panic)]
-
-#[test]
-#[allow_fail]
-fn test1() {
-    #[cfg(not(panic = "abort"))]
-    panic!();
-}
-
-#[test]
-#[allow_fail]
-fn test2() {
-    assert!(true);
-}
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 27d59bc01f2..da7a19139c6 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -922,10 +922,11 @@ pub fn make_test_description<R: Read>(
         name,
         ignore,
         should_panic,
-        allow_fail: false,
         compile_fail: false,
         no_run: false,
         test_type: test::TestType::Unknown,
+        #[cfg(bootstrap)]
+        allow_fail: false,
     }
 }