about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/glue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs11
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs8
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0794.md64
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs11
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs17
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs47
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs19
-rw-r--r--library/core/src/hash/mod.rs2
-rw-r--r--library/std/src/os/android/net.rs4
-rw-r--r--library/std/src/os/linux/net.rs4
-rw-r--r--library/std/src/os/net/linux_ext/addr.rs6
-rw-r--r--library/std/src/os/net/linux_ext/mod.rs2
-rw-r--r--library/std/src/os/unix/net/addr.rs4
-rw-r--r--library/std/src/os/unix/net/datagram.rs9
-rw-r--r--library/std/src/os/unix/net/listener.rs3
-rw-r--r--library/std/src/os/unix/net/stream.rs3
-rw-r--r--src/bootstrap/test.rs6
-rw-r--r--src/librustdoc/html/format.rs14
-rw-r--r--src/tools/miri/src/machine.rs2
-rw-r--r--src/tools/tidy/src/bins.rs2
-rw-r--r--src/tools/tidy/src/debug_artifacts.rs12
-rw-r--r--src/tools/tidy/src/features.rs17
-rw-r--r--src/tools/tidy/src/main.rs21
-rw-r--r--src/tools/tidy/src/style.rs31
-rw-r--r--src/tools/tidy/src/target_specific_tests.rs100
-rw-r--r--src/tools/tidy/src/ui_tests.rs122
-rw-r--r--src/tools/tidy/src/walk.rs30
-rw-r--r--tests/ui/async-await/async-trait-fn.current.stderr42
-rw-r--r--tests/ui/async-await/async-trait-fn.next.stderr42
-rw-r--r--tests/ui/async-await/async-trait-fn.rs1
-rw-r--r--tests/ui/async-await/async-trait-fn.stderr6
-rw-r--r--tests/ui/async-await/edition-deny-async-fns-2015.current.stderr (renamed from tests/ui/async-await/edition-deny-async-fns-2015.stderr)20
-rw-r--r--tests/ui/async-await/edition-deny-async-fns-2015.next.stderr98
-rw-r--r--tests/ui/async-await/edition-deny-async-fns-2015.rs2
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.current.stderr16
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.next.stderr16
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.rs15
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.stderr16
-rw-r--r--tests/ui/async-await/in-trait/return-type-suggestion.current.stderr (renamed from tests/ui/async-await/in-trait/return-type-suggestion.stderr)4
-rw-r--r--tests/ui/async-await/in-trait/return-type-suggestion.next.stderr23
-rw-r--r--tests/ui/async-await/in-trait/return-type-suggestion.rs2
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.full.stderr17
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.min.stderr18
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr (renamed from tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr)6
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr24
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-with-rpit.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr (renamed from tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr)4
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr (renamed from tests/ui/impl-trait/in-trait/generics-mismatch.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/generics-mismatch.rs3
-rw-r--r--tests/ui/late-bound-lifetimes/issue-80618.rs8
-rw-r--r--tests/ui/late-bound-lifetimes/issue-80618.stderr15
-rw-r--r--tests/ui/methods/method-call-lifetime-args-fail.stderr31
-rw-r--r--tests/ui/methods/method-call-lifetime-args.stderr5
64 files changed, 760 insertions, 313 deletions
diff --git a/.gitignore b/.gitignore
index ce797a7a837..04d2597ecc6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@ no_llvm_build
 /llvm/
 /mingw-build/
 build/
+!/compiler/rustc_mir_build/src/build/
 /build-rust-analyzer/
 /dist/
 /unicode-downloads
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index d0af3729b23..1b8e9312e2f 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -346,17 +346,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                 crate::abi::codegen_return(fx);
             }
             TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
-                if !fx.tcx.sess.overflow_checks() {
-                    let overflow_not_to_check = match msg {
-                        AssertKind::OverflowNeg(..) => true,
-                        AssertKind::Overflow(op, ..) => op.is_checkable(),
-                        _ => false,
-                    };
-                    if overflow_not_to_check {
-                        let target = fx.get_block(*target);
-                        fx.bcx.ins().jump(target, &[]);
-                        continue;
-                    }
+                if !fx.tcx.sess.overflow_checks() && msg.is_optional_overflow_check() {
+                    let target = fx.get_block(*target);
+                    fx.bcx.ins().jump(target, &[]);
+                    continue;
                 }
                 let cond = codegen_operand(fx, cond).load_scalar(fx);
 
diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs
index 0f6e6032f9b..c34f1dbf856 100644
--- a/compiler/rustc_codegen_ssa/src/glue.rs
+++ b/compiler/rustc_codegen_ssa/src/glue.rs
@@ -46,7 +46,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 // NOTE: ideally, we want the effects of both `unchecked_smul` and `unchecked_umul`
                 // (resulting in `mul nsw nuw` in LLVM IR), since we know that the multiplication
                 // cannot signed wrap, and that both operands are non-negative. But at the time of writing,
-                // `BuilderMethods` can't do this, and it doesn't seem to enable any further optimizations.
+                // the `LLVM-C` binding can't do this, and it doesn't seem to enable any further optimizations.
                 bx.unchecked_smul(info.unwrap(), bx.const_usize(unit.size.bytes())),
                 bx.const_usize(unit.align.abi.bytes()),
             )
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 71c71d59b7a..f9aa2aecf65 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -563,15 +563,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         // with #[rustc_inherit_overflow_checks] and inlined from
         // another crate (mostly core::num generic/#[inline] fns),
         // while the current crate doesn't use overflow checks.
-        if !bx.cx().check_overflow() {
-            let overflow_not_to_check = match msg {
-                AssertKind::OverflowNeg(..) => true,
-                AssertKind::Overflow(op, ..) => op.is_checkable(),
-                _ => false,
-            };
-            if overflow_not_to_check {
-                const_cond = Some(expected);
-            }
+        if !bx.cx().check_overflow() && msg.is_optional_overflow_check() {
+            const_cond = Some(expected);
         }
 
         // Don't codegen the panic block if success if known.
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 92fa59aec6e..c134d3a6b2f 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -155,7 +155,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
 
     /// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually
     /// check for overflow.
-    fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
+    fn ignore_optional_overflow_checks(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
 
     /// Entry point for obtaining the MIR of anything that should get evaluated.
     /// So not just functions and shims, but also const/static initializers, anonymous
@@ -474,7 +474,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
     }
 
     #[inline(always)]
-    fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
+    fn ignore_optional_overflow_checks(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
         false
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 685a5599cde..c2d1bc11c37 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -138,12 +138,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             Assert { ref cond, expected, ref msg, target, cleanup } => {
-                let ignored = M::ignore_checkable_overflow_assertions(self)
-                    && match msg {
-                        mir::AssertKind::OverflowNeg(..) => true,
-                        mir::AssertKind::Overflow(op, ..) => op.is_checkable(),
-                        _ => false,
-                    };
+                let ignored =
+                    M::ignore_optional_overflow_checks(self) && msg.is_optional_overflow_check();
                 let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?;
                 if ignored || expected == cond_val {
                     self.go_to_block(target);
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index df857be85ad..d104ff0891d 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -513,6 +513,7 @@ E0790: include_str!("./error_codes/E0790.md"),
 E0791: include_str!("./error_codes/E0791.md"),
 E0792: include_str!("./error_codes/E0792.md"),
 E0793: include_str!("./error_codes/E0793.md"),
+E0794: include_str!("./error_codes/E0794.md"),
 }
 
 // Undocumented removed error codes. Note that many removed error codes are documented.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0794.md b/compiler/rustc_error_codes/src/error_codes/E0794.md
new file mode 100644
index 00000000000..a33802885c0
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0794.md
@@ -0,0 +1,64 @@
+A lifetime parameter of a function definition is called *late-bound* if it both:
+
+1. appears in an argument type
+2. does not appear in a generic type constraint
+
+You cannot specify lifetime arguments for late-bound lifetime parameters.
+
+Erroneous code example:
+
+```compile_fail,E0794
+fn foo<'a>(x: &'a str) -> &'a str { x }
+let _ = foo::<'static>;
+```
+
+The type of a concrete instance of a generic function is universally quantified
+over late-bound lifetime parameters. This is because we want the function to
+work for any lifetime substituted for the late-bound lifetime parameter, no
+matter where the function is called. Consequently, it doesn't make sense to
+specify arguments for late-bound lifetime parameters, since they are not
+resolved until the function's call site(s).
+
+To fix the issue, remove the specified lifetime:
+
+```
+fn foo<'a>(x: &'a str) -> &'a str { x }
+let _ = foo;
+```
+
+### Additional information
+
+Lifetime parameters that are not late-bound are called *early-bound*.
+Confusion may arise from the fact that late-bound and early-bound
+lifetime parameters are declared the same way in function definitions.
+When referring to a function pointer type, universal quantification over
+late-bound lifetime parameters can be made explicit:
+
+```
+trait BarTrait<'a> {}
+
+struct Bar<'a> {
+    s: &'a str
+}
+
+impl<'a> BarTrait<'a> for Bar<'a> {}
+
+fn bar<'a, 'b, T>(x: &'a str, _t: T) -> &'a str
+where T: BarTrait<'b>
+{
+    x
+}
+
+let bar_fn: for<'a> fn(&'a str, Bar<'static>) -> &'a str = bar; // OK
+let bar_fn2 = bar::<'static, Bar>; // Not allowed
+let bar_fn3 = bar::<Bar>; // OK
+```
+
+In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
+`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
+where `'a` is universally quantified and `'b` is substituted by a specific
+lifetime. It is not allowed to explicitly specify early-bound lifetime
+arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
+see issue #42868: https://github.com/rust-lang/rust/issues/42868), although the
+types that are constrained by early-bound parameters can be specified (as for
+`bar_fn3`).
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 2f4963f6bc3..3b5c67de239 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -612,7 +612,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
         if position == GenericArgPosition::Value
             && args.num_lifetime_params() != param_counts.lifetimes
         {
-            let mut err = tcx.sess.struct_span_err(span, msg);
+            let mut err = struct_span_err!(tcx.sess, span, E0794, "{}", msg);
             err.span_note(span_late, note);
             err.emit();
         } else {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 6e6f8c1533b..32b6aeed5f8 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1205,6 +1205,17 @@ fn compare_number_of_generics<'tcx>(
         return Ok(());
     }
 
+    // We never need to emit a separate error for RPITITs, since if an RPITIT
+    // has mismatched type or const generic arguments, then the method that it's
+    // inheriting the generics from will also have mismatched arguments, and
+    // we'll report an error for that instead. Delay a bug for safety, though.
+    if tcx.opt_rpitit_info(trait_.def_id).is_some() {
+        return Err(tcx.sess.delay_span_bug(
+            rustc_span::DUMMY_SP,
+            "errors comparing numbers of generics of trait/impl functions were not emitted",
+        ));
+    }
+
     let matchings = [
         ("type", trait_own_counts.types, impl_own_counts.types),
         ("const", trait_own_counts.consts, impl_own_counts.consts),
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 7d515bb0f5a..42c0354d03a 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1268,6 +1268,13 @@ impl<'tcx> BasicBlockData<'tcx> {
 }
 
 impl<O> AssertKind<O> {
+    /// Returns true if this an overflow checking assertion controlled by -C overflow-checks.
+    pub fn is_optional_overflow_check(&self) -> bool {
+        use AssertKind::*;
+        use BinOp::*;
+        matches!(self, OverflowNeg(..) | Overflow(Add | Sub | Mul | Shl | Shr, ..))
+    }
+
     /// Getting a description does not require `O` to be printable, and does not
     /// require allocation.
     /// The caller is expected to handle `BoundsCheck` separately.
@@ -1992,16 +1999,6 @@ impl BorrowKind {
     }
 }
 
-impl BinOp {
-    /// The checkable operators are those whose overflow checking behavior is controlled by
-    /// -Coverflow-checks option. The remaining operators have either no overflow conditions (e.g.,
-    /// BitAnd, BitOr, BitXor) or are always checked for overflow (e.g., Div, Rem).
-    pub fn is_checkable(self) -> bool {
-        use self::BinOp::*;
-        matches!(self, Add | Sub | Mul | Shl | Shr)
-    }
-}
-
 impl<'tcx> Debug for Rvalue<'tcx> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         use self::Rvalue::*;
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index a28ecfa9bdc..b16b6616415 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -646,8 +646,7 @@ pub enum TerminatorKind<'tcx> {
     /// When overflow checking is disabled and this is run-time MIR (as opposed to compile-time MIR
     /// that is used for CTFE), the following variants of this terminator behave as `goto target`:
     /// - `OverflowNeg(..)`,
-    /// - `Overflow(op, ..)` if op is a "checkable" operation (add, sub, mul, shl, shr, but NOT
-    /// div or rem).
+    /// - `Overflow(op, ..)` if op is add, sub, mul, shl, shr, but NOT div or rem.
     Assert {
         cond: Operand<'tcx>,
         expected: bool,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 9f48986b1ad..140d1154718 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -73,19 +73,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             ExprKind::Binary { op, lhs, rhs } => {
                 let lhs = unpack!(
-                    block =
-                        this.as_operand(block, scope, &this.thir[lhs], LocalInfo::Boring, NeedsTemporary::Maybe)
+                    block = this.as_operand(
+                        block,
+                        scope,
+                        &this.thir[lhs],
+                        LocalInfo::Boring,
+                        NeedsTemporary::Maybe
+                    )
                 );
                 let rhs = unpack!(
-                    block =
-                        this.as_operand(block, scope, &this.thir[rhs], LocalInfo::Boring, NeedsTemporary::No)
+                    block = this.as_operand(
+                        block,
+                        scope,
+                        &this.thir[rhs],
+                        LocalInfo::Boring,
+                        NeedsTemporary::No
+                    )
                 );
                 this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs)
             }
             ExprKind::Unary { op, arg } => {
                 let arg = unpack!(
-                    block =
-                        this.as_operand(block, scope, &this.thir[arg], LocalInfo::Boring, NeedsTemporary::No)
+                    block = this.as_operand(
+                        block,
+                        scope,
+                        &this.thir[arg],
+                        LocalInfo::Boring,
+                        NeedsTemporary::No
+                    )
                 );
                 // Check for -MIN on signed integers
                 if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() {
@@ -272,8 +287,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             ExprKind::Pointer { cast, source } => {
                 let source = unpack!(
-                    block =
-                        this.as_operand(block, scope, &this.thir[source], LocalInfo::Boring, NeedsTemporary::No)
+                    block = this.as_operand(
+                        block,
+                        scope,
+                        &this.thir[source],
+                        LocalInfo::Boring,
+                        NeedsTemporary::No
+                    )
                 );
                 block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
             }
@@ -502,8 +522,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     Category::of(&expr.kind),
                     Some(Category::Rvalue(RvalueFunc::AsRvalue) | Category::Constant)
                 ));
-                let operand =
-                    unpack!(block = this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No));
+                let operand = unpack!(
+                    block =
+                        this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No)
+                );
                 block.and(Rvalue::Use(operand))
             }
         }
@@ -662,8 +684,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // Repeating a const does nothing
         } else {
             // For a non-const, we may need to generate an appropriate `Drop`
-            let value_operand =
-                unpack!(block = this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No));
+            let value_operand = unpack!(
+                block = this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No)
+            );
             if let Operand::Move(to_drop) = value_operand {
                 let success = this.cfg.start_new_block();
                 this.cfg.terminate(
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 22785dfd2ce..2d52102db2c 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -2252,7 +2252,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 user_ty: None,
                 source_info,
                 internal: false,
-                local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::RefForGuard))),
+                local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(
+                    BindingForm::RefForGuard,
+                ))),
             });
             self.var_debug_info.push(VarDebugInfo {
                 name,
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 6814fd4cb35..80d8b27336c 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -876,21 +876,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 } => {
                     self.local_decls[local].mutability = mutability;
                     self.local_decls[local].source_info.scope = self.source_scope;
-                    **self.local_decls[local].local_info.as_mut().assert_crate_local() = if let Some(kind) = param.self_kind {
-                        LocalInfo::User(
-                            BindingForm::ImplicitSelf(kind),
-                        )
-                    } else {
-                        let binding_mode = ty::BindingMode::BindByValue(mutability);
-                        LocalInfo::User(BindingForm::Var(
-                            VarBindingForm {
+                    **self.local_decls[local].local_info.as_mut().assert_crate_local() =
+                        if let Some(kind) = param.self_kind {
+                            LocalInfo::User(BindingForm::ImplicitSelf(kind))
+                        } else {
+                            let binding_mode = ty::BindingMode::BindByValue(mutability);
+                            LocalInfo::User(BindingForm::Var(VarBindingForm {
                                 binding_mode,
                                 opt_ty_info: param.ty_span,
                                 opt_match_place: Some((None, span)),
                                 pat_span: span,
-                            },
-                        ))
-                    };
+                            }))
+                        };
                     self.var_indices.insert(var, LocalsForNode::One(local));
                 }
                 _ => {
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 3bdde0993b9..4e7bae7bcb0 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -834,7 +834,7 @@ mod impls {
 
                 #[inline]
                 fn hash_slice<H: ~const Hasher>(data: &[$ty], state: &mut H) {
-                    let newlen = data.len() * mem::size_of::<$ty>();
+                    let newlen = mem::size_of_val(data);
                     let ptr = data.as_ptr() as *const u8;
                     // SAFETY: `ptr` is valid and aligned, as this macro is only used
                     // for numeric primitives which have no padding. The new slice only
diff --git a/library/std/src/os/android/net.rs b/library/std/src/os/android/net.rs
index 7cecd1bbfaa..4e88ab8ff5c 100644
--- a/library/std/src/os/android/net.rs
+++ b/library/std/src/os/android/net.rs
@@ -1,8 +1,8 @@
 //! Android-specific networking functionality.
 
-#![unstable(feature = "tcp_quickack", issue = "96256")]
+#![stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 
-#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 pub use crate::os::net::linux_ext::addr::SocketAddrExt;
 
 #[unstable(feature = "tcp_quickack", issue = "96256")]
diff --git a/library/std/src/os/linux/net.rs b/library/std/src/os/linux/net.rs
index 94081c8dd31..fcb3bb83485 100644
--- a/library/std/src/os/linux/net.rs
+++ b/library/std/src/os/linux/net.rs
@@ -1,8 +1,8 @@
 //! Linux-specific networking functionality.
 
-#![unstable(feature = "tcp_quickack", issue = "96256")]
+#![stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 
-#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 pub use crate::os::net::linux_ext::addr::SocketAddrExt;
 
 #[unstable(feature = "tcp_quickack", issue = "96256")]
diff --git a/library/std/src/os/net/linux_ext/addr.rs b/library/std/src/os/net/linux_ext/addr.rs
index 85065984fbb..ea8102c9cc0 100644
--- a/library/std/src/os/net/linux_ext/addr.rs
+++ b/library/std/src/os/net/linux_ext/addr.rs
@@ -4,7 +4,7 @@ use crate::os::unix::net::SocketAddr;
 use crate::sealed::Sealed;
 
 /// Platform-specific extensions to [`SocketAddr`].
-#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 pub trait SocketAddrExt: Sealed {
     /// Creates a Unix socket address in the abstract namespace.
     ///
@@ -22,7 +22,6 @@ pub trait SocketAddrExt: Sealed {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixListener, SocketAddr};
     /// use std::os::linux::net::SocketAddrExt;
     ///
@@ -38,6 +37,7 @@ pub trait SocketAddrExt: Sealed {
     ///     Ok(())
     /// }
     /// ```
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     fn from_abstract_name<N>(name: N) -> crate::io::Result<SocketAddr>
     where
         N: AsRef<[u8]>;
@@ -47,7 +47,6 @@ pub trait SocketAddrExt: Sealed {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixListener, SocketAddr};
     /// use std::os::linux::net::SocketAddrExt;
     ///
@@ -60,5 +59,6 @@ pub trait SocketAddrExt: Sealed {
     ///     Ok(())
     /// }
     /// ```
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     fn as_abstract_name(&self) -> Option<&[u8]>;
 }
diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs
index 318ebacfd7a..e7423dce613 100644
--- a/library/std/src/os/net/linux_ext/mod.rs
+++ b/library/std/src/os/net/linux_ext/mod.rs
@@ -2,7 +2,7 @@
 
 #![doc(cfg(any(target_os = "linux", target_os = "android")))]
 
-#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 pub(crate) mod addr;
 
 #[unstable(feature = "tcp_quickack", issue = "96256")]
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index ece2b33bddf..52a0da5bf1a 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -245,12 +245,12 @@ impl SocketAddr {
     }
 }
 
-#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 impl Sealed for SocketAddr {}
 
 #[doc(cfg(any(target_os = "android", target_os = "linux")))]
 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
-#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
 impl linux_ext::addr::SocketAddrExt for SocketAddr {
     fn as_abstract_name(&self) -> Option<&[u8]> {
         if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 272b4f5dcd5..e64569758a0 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -102,7 +102,6 @@ impl UnixDatagram {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixDatagram};
     ///
     /// fn main() -> std::io::Result<()> {
@@ -119,7 +118,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixDatagram> {
         unsafe {
             let socket = UnixDatagram::unbound()?;
@@ -217,7 +216,6 @@ impl UnixDatagram {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixDatagram};
     ///
     /// fn main() -> std::io::Result<()> {
@@ -235,7 +233,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     pub fn connect_addr(&self, socket_addr: &SocketAddr) -> io::Result<()> {
         unsafe {
             cvt(libc::connect(
@@ -523,7 +521,6 @@ impl UnixDatagram {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixDatagram};
     ///
     /// fn main() -> std::io::Result<()> {
@@ -535,7 +532,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     pub fn send_to_addr(&self, buf: &[u8], socket_addr: &SocketAddr) -> io::Result<usize> {
         unsafe {
             let count = cvt(libc::sendto(
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index 02090afc82f..83f0debe676 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -90,7 +90,6 @@ impl UnixListener {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixListener};
     ///
     /// fn main() -> std::io::Result<()> {
@@ -107,7 +106,7 @@ impl UnixListener {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> {
         unsafe {
             let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index dff8f6e8567..65cb4ae07a5 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -106,7 +106,6 @@ impl UnixStream {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(unix_socket_abstract)]
     /// use std::os::unix::net::{UnixListener, UnixStream};
     ///
     /// fn main() -> std::io::Result<()> {
@@ -123,7 +122,7 @@ impl UnixStream {
     ///     Ok(())
     /// }
     /// ````
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
+    #[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
     pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
         unsafe {
             let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index f5d680df113..baddc9da48d 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1118,7 +1118,11 @@ impl Step for Tidy {
         cmd.arg(&builder.src);
         cmd.arg(&builder.initial_cargo);
         cmd.arg(&builder.out);
-        cmd.arg(builder.jobs().to_string());
+        // Tidy is heavily IO constrained. Still respect `-j`, but use a higher limit if `jobs` hasn't been configured.
+        let jobs = builder.config.jobs.unwrap_or_else(|| {
+            8 * std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
+        });
+        cmd.arg(jobs.to_string());
         if builder.is_verbose() {
             cmd.arg("--verbose");
         }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 27010b771d3..d526a8be081 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1502,9 +1502,9 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
     tcx: TyCtxt<'tcx>,
     item_did: DefId,
 ) -> impl fmt::Display + 'a + Captures<'tcx> {
-    let to_print = match visibility {
-        None => String::new(),
-        Some(ty::Visibility::Public) => "pub ".to_owned(),
+    let to_print: Cow<'static, str> = match visibility {
+        None => "".into(),
+        Some(ty::Visibility::Public) => "pub ".into(),
         Some(ty::Visibility::Restricted(vis_did)) => {
             // FIXME(camelid): This may not work correctly if `item_did` is a module.
             //                 However, rustdoc currently never displays a module's
@@ -1512,17 +1512,17 @@ pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
             let parent_module = find_nearest_parent_module(tcx, item_did);
 
             if vis_did.is_crate_root() {
-                "pub(crate) ".to_owned()
+                "pub(crate) ".into()
             } else if parent_module == Some(vis_did) {
                 // `pub(in foo)` where `foo` is the parent module
                 // is the same as no visibility modifier
-                String::new()
+                "".into()
             } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
                 == Some(vis_did)
             {
-                "pub(super) ".to_owned()
+                "pub(super) ".into()
             } else {
-                format!("pub(in {}) ", tcx.def_path_str(vis_did))
+                format!("pub(in {}) ", tcx.def_path_str(vis_did)).into()
             }
         }
     };
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index eaa441d22ec..c4baeb2a73b 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -822,7 +822,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     }
 
     #[inline(always)]
-    fn ignore_checkable_overflow_assertions(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
+    fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
         !ecx.tcx.sess.overflow_checks()
     }
 
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index 2d6abe59343..070ce93f97c 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -103,7 +103,7 @@ mod os_impl {
 
         // FIXME: we don't need to look at all binaries, only files that have been modified in this branch
         // (e.g. using `git ls-files`).
-        walk_no_read(path, |path| filter_dirs(path) || path.ends_with("src/etc"), &mut |entry| {
+        walk_no_read(&[path], |path| filter_dirs(path) || path.ends_with("src/etc"), &mut |entry| {
             let file = entry.path();
             let extension = file.extension();
             let scripts = ["py", "sh", "ps1"];
diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs
index 2241375eaae..84b13306805 100644
--- a/src/tools/tidy/src/debug_artifacts.rs
+++ b/src/tools/tidy/src/debug_artifacts.rs
@@ -1,21 +1,15 @@
 //! Tidy check to prevent creation of unnecessary debug artifacts while running tests.
 
-use crate::walk::{filter_dirs, walk};
+use crate::walk::{filter_dirs, filter_not_rust, walk};
 use std::path::Path;
 
 const GRAPHVIZ_POSTFLOW_MSG: &str = "`borrowck_graphviz_postflow` attribute in test";
 
 pub fn check(test_dir: &Path, bad: &mut bool) {
-    walk(test_dir, filter_dirs, &mut |entry, contents| {
-        let filename = entry.path();
-        let is_rust = filename.extension().map_or(false, |ext| ext == "rs");
-        if !is_rust {
-            return;
-        }
-
+    walk(test_dir, |path| filter_dirs(path) || filter_not_rust(path), &mut |entry, contents| {
         for (i, line) in contents.lines().enumerate() {
             if line.contains("borrowck_graphviz_postflow") {
-                tidy_error!(bad, "{}:{}: {}", filename.display(), i + 1, GRAPHVIZ_POSTFLOW_MSG);
+                tidy_error!(bad, "{}:{}: {}", entry.path().display(), i + 1, GRAPHVIZ_POSTFLOW_MSG);
             }
         }
     });
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 6d94417a10f..f18feda533c 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -9,8 +9,9 @@
 //! * All unstable lang features have tests to ensure they are actually unstable.
 //! * Language features in a group are sorted by feature name.
 
-use crate::walk::{filter_dirs, walk, walk_many};
+use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many};
 use std::collections::hash_map::{Entry, HashMap};
+use std::ffi::OsStr;
 use std::fmt;
 use std::fs;
 use std::num::NonZeroU32;
@@ -101,17 +102,15 @@ pub fn check(
             &tests_path.join("rustdoc-ui"),
             &tests_path.join("rustdoc"),
         ],
-        filter_dirs,
+        |path| {
+            filter_dirs(path)
+                || filter_not_rust(path)
+                || path.file_name() == Some(OsStr::new("features.rs"))
+                || path.file_name() == Some(OsStr::new("diagnostic_list.rs"))
+        },
         &mut |entry, contents| {
             let file = entry.path();
             let filename = file.file_name().unwrap().to_string_lossy();
-            if !filename.ends_with(".rs")
-                || filename == "features.rs"
-                || filename == "diagnostic_list.rs"
-            {
-                return;
-            }
-
             let filen_underscore = filename.replace('-', "_").replace(".rs", "");
             let filename_is_gate_test = test_filen_gate(&filen_underscore, &mut features);
 
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index d98758ace4f..f59406c404b 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -13,7 +13,7 @@ use std::path::PathBuf;
 use std::process;
 use std::str::FromStr;
 use std::sync::atomic::{AtomicBool, Ordering};
-use std::thread::{scope, ScopedJoinHandle};
+use std::thread::{self, scope, ScopedJoinHandle};
 
 fn main() {
     let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
@@ -55,16 +55,28 @@ fn main() {
             VecDeque::with_capacity(concurrency.get());
 
         macro_rules! check {
-            ($p:ident $(, $args:expr)* ) => {
+            ($p:ident) => {
+                check!(@ $p, name=format!("{}", stringify!($p)));
+            };
+            ($p:ident, $path:expr $(, $args:expr)* ) => {
+                let shortened = $path.strip_prefix(&root_path).unwrap();
+                let name = if shortened == std::path::Path::new("") {
+                    format!("{} (.)", stringify!($p))
+                } else {
+                    format!("{} ({})", stringify!($p), shortened.display())
+                };
+                check!(@ $p, name=name, $path $(,$args)*);
+            };
+            (@ $p:ident, name=$name:expr $(, $args:expr)* ) => {
                 drain_handles(&mut handles);
 
-                let handle = s.spawn(|| {
+                let handle = thread::Builder::new().name($name).spawn_scoped(s, || {
                     let mut flag = false;
                     $p::check($($args, )* &mut flag);
                     if (flag) {
                         bad.store(true, Ordering::Relaxed);
                     }
-                });
+                }).unwrap();
                 handles.push_back(handle);
             }
         }
@@ -108,7 +120,6 @@ fn main() {
         check!(edition, &library_path);
 
         check!(alphabetical, &src_path);
-        check!(alphabetical, &tests_path);
         check!(alphabetical, &compiler_path);
         check!(alphabetical, &library_path);
 
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 75a4586cb7f..a965c98f484 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -19,7 +19,7 @@
 
 use crate::walk::{filter_dirs, walk};
 use regex::{Regex, RegexSet};
-use std::path::Path;
+use std::{ffi::OsStr, path::Path};
 
 /// Error code markdown is restricted to 80 columns because they can be
 /// displayed on the console with --example.
@@ -228,21 +228,33 @@ fn is_unexplained_ignore(extension: &str, line: &str) -> bool {
 
 pub fn check(path: &Path, bad: &mut bool) {
     fn skip(path: &Path) -> bool {
-        filter_dirs(path) || skip_markdown_path(path)
+        if path.file_name().map_or(false, |name| name.to_string_lossy().starts_with(".#")) {
+            // vim or emacs temporary file
+            return true;
+        }
+
+        if filter_dirs(path) || skip_markdown_path(path) {
+            return true;
+        }
+
+        let extensions = ["rs", "py", "js", "sh", "c", "cpp", "h", "md", "css", "ftl", "goml"];
+        if extensions.iter().all(|e| path.extension() != Some(OsStr::new(e))) {
+            return true;
+        }
+
+        // We only check CSS files in rustdoc.
+        path.extension().map_or(false, |e| e == "css") && !is_in(path, "src", "librustdoc")
     }
+
     let problematic_consts_strings: Vec<String> = (PROBLEMATIC_CONSTS.iter().map(u32::to_string))
         .chain(PROBLEMATIC_CONSTS.iter().map(|v| format!("{:x}", v)))
         .chain(PROBLEMATIC_CONSTS.iter().map(|v| format!("{:X}", v)))
         .collect();
     let problematic_regex = RegexSet::new(problematic_consts_strings.as_slice()).unwrap();
+
     walk(path, skip, &mut |entry, contents| {
         let file = entry.path();
         let filename = file.file_name().unwrap().to_string_lossy();
-        let extensions =
-            [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl", ".goml"];
-        if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") {
-            return;
-        }
 
         let is_style_file = filename.ends_with(".css");
         let under_rustfmt = filename.ends_with(".rs") &&
@@ -253,11 +265,6 @@ pub fn check(path: &Path, bad: &mut bool) {
                     a.ends_with("src/doc/book")
             });
 
-        if is_style_file && !is_in(file, "src", "librustdoc") {
-            // We only check CSS files in rustdoc.
-            return;
-        }
-
         if contents.is_empty() {
             tidy_error!(bad, "{}: empty file", file.display());
         }
diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs
index f41fa4fcce1..e0fa6aceb85 100644
--- a/src/tools/tidy/src/target_specific_tests.rs
+++ b/src/tools/tidy/src/target_specific_tests.rs
@@ -4,6 +4,8 @@
 use std::collections::BTreeMap;
 use std::path::Path;
 
+use crate::walk::filter_not_rust;
+
 const COMMENT: &str = "//";
 const LLVM_COMPONENTS_HEADER: &str = "needs-llvm-components:";
 const COMPILE_FLAGS_HEADER: &str = "compile-flags:";
@@ -35,61 +37,57 @@ struct RevisionInfo<'a> {
 }
 
 pub fn check(path: &Path, bad: &mut bool) {
-    crate::walk::walk(
-        path,
-        |path| path.extension().map(|p| p == "rs") == Some(false),
-        &mut |entry, content| {
-            let file = entry.path().display();
-            let mut header_map = BTreeMap::new();
-            iter_header(content, &mut |cfg, directive| {
-                if let Some(value) = directive.strip_prefix(LLVM_COMPONENTS_HEADER) {
-                    let info = header_map.entry(cfg).or_insert(RevisionInfo::default());
-                    let comp_vec = info.llvm_components.get_or_insert(Vec::new());
-                    for component in value.split(' ') {
-                        let component = component.trim();
-                        if !component.is_empty() {
-                            comp_vec.push(component);
-                        }
-                    }
-                } else if directive.starts_with(COMPILE_FLAGS_HEADER) {
-                    let compile_flags = &directive[COMPILE_FLAGS_HEADER.len()..];
-                    if let Some((_, v)) = compile_flags.split_once("--target") {
-                        if let Some((arch, _)) =
-                            v.trim_start_matches(|c| c == ' ' || c == '=').split_once("-")
-                        {
-                            let info = header_map.entry(cfg).or_insert(RevisionInfo::default());
-                            info.target_arch.replace(arch);
-                        } else {
-                            eprintln!("{file}: seems to have a malformed --target value");
-                            *bad = true;
-                        }
+    crate::walk::walk(path, filter_not_rust, &mut |entry, content| {
+        let file = entry.path().display();
+        let mut header_map = BTreeMap::new();
+        iter_header(content, &mut |cfg, directive| {
+            if let Some(value) = directive.strip_prefix(LLVM_COMPONENTS_HEADER) {
+                let info = header_map.entry(cfg).or_insert(RevisionInfo::default());
+                let comp_vec = info.llvm_components.get_or_insert(Vec::new());
+                for component in value.split(' ') {
+                    let component = component.trim();
+                    if !component.is_empty() {
+                        comp_vec.push(component);
                     }
                 }
-            });
-            for (rev, RevisionInfo { target_arch, llvm_components }) in &header_map {
-                let rev = rev.unwrap_or("[unspecified]");
-                match (target_arch, llvm_components) {
-                    (None, None) => {}
-                    (Some(_), None) => {
-                        eprintln!(
-                            "{}: revision {} should specify `{}` as it has `--target` set",
-                            file, rev, LLVM_COMPONENTS_HEADER
-                        );
+            } else if directive.starts_with(COMPILE_FLAGS_HEADER) {
+                let compile_flags = &directive[COMPILE_FLAGS_HEADER.len()..];
+                if let Some((_, v)) = compile_flags.split_once("--target") {
+                    if let Some((arch, _)) =
+                        v.trim_start_matches(|c| c == ' ' || c == '=').split_once("-")
+                    {
+                        let info = header_map.entry(cfg).or_insert(RevisionInfo::default());
+                        info.target_arch.replace(arch);
+                    } else {
+                        eprintln!("{file}: seems to have a malformed --target value");
                         *bad = true;
                     }
-                    (None, Some(_)) => {
-                        eprintln!(
-                            "{}: revision {} should not specify `{}` as it doesn't need `--target`",
-                            file, rev, LLVM_COMPONENTS_HEADER
-                        );
-                        *bad = true;
-                    }
-                    (Some(_), Some(_)) => {
-                        // FIXME: check specified components against the target architectures we
-                        // gathered.
-                    }
                 }
             }
-        },
-    );
+        });
+        for (rev, RevisionInfo { target_arch, llvm_components }) in &header_map {
+            let rev = rev.unwrap_or("[unspecified]");
+            match (target_arch, llvm_components) {
+                (None, None) => {}
+                (Some(_), None) => {
+                    eprintln!(
+                        "{}: revision {} should specify `{}` as it has `--target` set",
+                        file, rev, LLVM_COMPONENTS_HEADER
+                    );
+                    *bad = true;
+                }
+                (None, Some(_)) => {
+                    eprintln!(
+                        "{}: revision {} should not specify `{}` as it doesn't need `--target`",
+                        file, rev, LLVM_COMPONENTS_HEADER
+                    );
+                    *bad = true;
+                }
+                (Some(_), Some(_)) => {
+                    // FIXME: check specified components against the target architectures we
+                    // gathered.
+                }
+            }
+        }
+    });
 }
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 15c36923e88..66f5c932be2 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -3,87 +3,83 @@
 //! - there are no stray `.stderr` files
 
 use ignore::Walk;
-use ignore::WalkBuilder;
+use std::collections::HashMap;
 use std::fs;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
 const ROOT_ENTRY_LIMIT: usize = 940;
 const ISSUES_ENTRY_LIMIT: usize = 1978;
 
-fn check_entries(path: &Path, bad: &mut bool) {
-    for dir in Walk::new(&path.join("ui")) {
+fn check_entries(tests_path: &Path, bad: &mut bool) {
+    let mut directories: HashMap<PathBuf, usize> = HashMap::new();
+
+    for dir in Walk::new(&tests_path.join("ui")) {
         if let Ok(entry) = dir {
-            if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) {
-                let dir_path = entry.path();
-                // Use special values for these dirs.
-                let is_root = path.join("ui") == dir_path;
-                let is_issues_dir = path.join("ui/issues") == dir_path;
-                let limit = if is_root {
-                    ROOT_ENTRY_LIMIT
-                } else if is_issues_dir {
-                    ISSUES_ENTRY_LIMIT
-                } else {
-                    ENTRY_LIMIT
-                };
+            let parent = entry.path().parent().unwrap().to_path_buf();
+            *directories.entry(parent).or_default() += 1;
+        }
+    }
 
-                let count = WalkBuilder::new(&dir_path)
-                    .max_depth(Some(1))
-                    .build()
-                    .into_iter()
-                    .collect::<Vec<_>>()
-                    .len()
-                    - 1; // remove the dir itself
+    for (dir_path, count) in directories {
+        // Use special values for these dirs.
+        let is_root = tests_path.join("ui") == dir_path;
+        let is_issues_dir = tests_path.join("ui/issues") == dir_path;
+        let limit = if is_root {
+            ROOT_ENTRY_LIMIT
+        } else if is_issues_dir {
+            ISSUES_ENTRY_LIMIT
+        } else {
+            ENTRY_LIMIT
+        };
 
-                if count > limit {
-                    tidy_error!(
-                        bad,
-                        "following path contains more than {} entries, \
-                            you should move the test to some relevant subdirectory (current: {}): {}",
-                        limit,
-                        count,
-                        dir_path.display()
-                    );
-                }
-            }
+        if count > limit {
+            tidy_error!(
+                bad,
+                "following path contains more than {} entries, \
+                    you should move the test to some relevant subdirectory (current: {}): {}",
+                limit,
+                count,
+                dir_path.display()
+            );
         }
     }
 }
 
 pub fn check(path: &Path, bad: &mut bool) {
     check_entries(&path, bad);
-    for path in &[&path.join("ui"), &path.join("ui-fulldeps")] {
-        crate::walk::walk_no_read(path, |_| false, &mut |entry| {
-            let file_path = entry.path();
-            if let Some(ext) = file_path.extension() {
-                if ext == "stderr" || ext == "stdout" {
-                    // Test output filenames have one of the formats:
-                    // ```
-                    // $testname.stderr
-                    // $testname.$mode.stderr
-                    // $testname.$revision.stderr
-                    // $testname.$revision.$mode.stderr
-                    // ```
-                    //
-                    // For now, just make sure that there is a corresponding
-                    // `$testname.rs` file.
-                    //
-                    // NB: We do not use file_stem() as some file names have multiple `.`s and we
-                    // must strip all of them.
-                    let testname =
-                        file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
-                    if !file_path.with_file_name(testname).with_extension("rs").exists() {
-                        tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path);
-                    }
+    let (ui, ui_fulldeps) = (path.join("ui"), path.join("ui-fulldeps"));
+    let paths = [ui.as_path(), ui_fulldeps.as_path()];
+    crate::walk::walk_no_read(&paths, |_| false, &mut |entry| {
+        let file_path = entry.path();
+        if let Some(ext) = file_path.extension() {
+            if ext == "stderr" || ext == "stdout" {
+                // Test output filenames have one of the formats:
+                // ```
+                // $testname.stderr
+                // $testname.$mode.stderr
+                // $testname.$revision.stderr
+                // $testname.$revision.$mode.stderr
+                // ```
+                //
+                // For now, just make sure that there is a corresponding
+                // `$testname.rs` file.
+                //
+                // NB: We do not use file_stem() as some file names have multiple `.`s and we
+                // must strip all of them.
+                let testname =
+                    file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
+                if !file_path.with_file_name(testname).with_extension("rs").exists() {
+                    tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path);
+                }
 
-                    if let Ok(metadata) = fs::metadata(file_path) {
-                        if metadata.len() == 0 {
-                            tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path);
-                        }
+                if let Ok(metadata) = fs::metadata(file_path) {
+                    if metadata.len() == 0 {
+                        tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path);
                     }
                 }
             }
-        });
-    }
+        }
+    });
 }
diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs
index 94152e75168..2ade22c209f 100644
--- a/src/tools/tidy/src/walk.rs
+++ b/src/tools/tidy/src/walk.rs
@@ -1,6 +1,6 @@
 use ignore::DirEntry;
 
-use std::{fs::File, io::Read, path::Path};
+use std::{ffi::OsStr, fs::File, io::Read, path::Path};
 
 /// The default directory filter.
 pub fn filter_dirs(path: &Path) -> bool {
@@ -33,23 +33,26 @@ pub fn filter_dirs(path: &Path) -> bool {
     skip.iter().any(|p| path.ends_with(p))
 }
 
-pub fn walk_many(
-    paths: &[&Path],
+/// Filter for only files that end in `.rs`.
+pub fn filter_not_rust(path: &Path) -> bool {
+    path.extension() != Some(OsStr::new("rs")) && !path.is_dir()
+}
+
+pub fn walk(
+    path: &Path,
     skip: impl Clone + Send + Sync + 'static + Fn(&Path) -> bool,
     f: &mut dyn FnMut(&DirEntry, &str),
 ) {
-    for path in paths {
-        walk(path, skip.clone(), f);
-    }
+    walk_many(&[path], skip, f);
 }
 
-pub fn walk(
-    path: &Path,
-    skip: impl Send + Sync + 'static + Fn(&Path) -> bool,
+pub fn walk_many(
+    paths: &[&Path],
+    skip: impl Clone + Send + Sync + 'static + Fn(&Path) -> bool,
     f: &mut dyn FnMut(&DirEntry, &str),
 ) {
     let mut contents = Vec::new();
-    walk_no_read(path, skip, &mut |entry| {
+    walk_no_read(paths, skip, &mut |entry| {
         contents.clear();
         let mut file = t!(File::open(entry.path()), entry.path());
         t!(file.read_to_end(&mut contents), entry.path());
@@ -62,11 +65,14 @@ pub fn walk(
 }
 
 pub(crate) fn walk_no_read(
-    path: &Path,
+    paths: &[&Path],
     skip: impl Send + Sync + 'static + Fn(&Path) -> bool,
     f: &mut dyn FnMut(&DirEntry),
 ) {
-    let mut walker = ignore::WalkBuilder::new(path);
+    let mut walker = ignore::WalkBuilder::new(paths[0]);
+    for path in &paths[1..] {
+        walker.add(path);
+    }
     let walker = walker.filter_entry(move |e| !skip(e.path()));
     for entry in walker.build() {
         if let Ok(entry) = entry {
diff --git a/tests/ui/async-await/async-trait-fn.current.stderr b/tests/ui/async-await/async-trait-fn.current.stderr
new file mode 100644
index 00000000000..7ccf2f2301d
--- /dev/null
+++ b/tests/ui/async-await/async-trait-fn.current.stderr
@@ -0,0 +1,42 @@
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:6:5
+   |
+LL |     async fn foo() {}
+   |     -----^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:7:5
+   |
+LL |     async fn bar(&self) {}
+   |     -----^^^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:8:5
+   |
+LL |     async fn baz() {
+   |     -----^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0706`.
diff --git a/tests/ui/async-await/async-trait-fn.next.stderr b/tests/ui/async-await/async-trait-fn.next.stderr
new file mode 100644
index 00000000000..7ccf2f2301d
--- /dev/null
+++ b/tests/ui/async-await/async-trait-fn.next.stderr
@@ -0,0 +1,42 @@
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:6:5
+   |
+LL |     async fn foo() {}
+   |     -----^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:7:5
+   |
+LL |     async fn bar(&self) {}
+   |     -----^^^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:8:5
+   |
+LL |     async fn baz() {
+   |     -----^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0706`.
diff --git a/tests/ui/async-await/async-trait-fn.rs b/tests/ui/async-await/async-trait-fn.rs
index e2062e82725..04123badb53 100644
--- a/tests/ui/async-await/async-trait-fn.rs
+++ b/tests/ui/async-await/async-trait-fn.rs
@@ -1,4 +1,5 @@
 // edition:2018
+
 trait T {
     async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
     async fn bar(&self) {} //~ ERROR functions in traits cannot be declared `async`
diff --git a/tests/ui/async-await/async-trait-fn.stderr b/tests/ui/async-await/async-trait-fn.stderr
index afbe25cf7ab..68ebe3507ac 100644
--- a/tests/ui/async-await/async-trait-fn.stderr
+++ b/tests/ui/async-await/async-trait-fn.stderr
@@ -1,5 +1,5 @@
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/async-trait-fn.rs:3:5
+  --> $DIR/async-trait-fn.rs:4:5
    |
 LL |     async fn foo() {}
    |     -----^^^^^^^^^
@@ -12,7 +12,7 @@ LL |     async fn foo() {}
    = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/async-trait-fn.rs:4:5
+  --> $DIR/async-trait-fn.rs:5:5
    |
 LL |     async fn bar(&self) {}
    |     -----^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     async fn bar(&self) {}
    = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/async-trait-fn.rs:5:5
+  --> $DIR/async-trait-fn.rs:6:5
    |
 LL |     async fn baz() {
    |     -----^^^^^^^^^
diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.current.stderr
index ba918eb28de..c47b99e657e 100644
--- a/tests/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/tests/ui/async-await/edition-deny-async-fns-2015.current.stderr
@@ -1,5 +1,5 @@
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:3:1
+  --> $DIR/edition-deny-async-fns-2015.rs:5:1
    |
 LL | async fn foo() {}
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -8,7 +8,7 @@ LL | async fn foo() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:5:12
+  --> $DIR/edition-deny-async-fns-2015.rs:7:12
    |
 LL | fn baz() { async fn foo() {} }
    |            ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -17,7 +17,7 @@ LL | fn baz() { async fn foo() {} }
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:7:1
+  --> $DIR/edition-deny-async-fns-2015.rs:9:1
    |
 LL | async fn async_baz() {
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -26,7 +26,7 @@ LL | async fn async_baz() {
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:8:5
+  --> $DIR/edition-deny-async-fns-2015.rs:10:5
    |
 LL |     async fn bar() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -35,7 +35,7 @@ LL |     async fn bar() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:14:5
+  --> $DIR/edition-deny-async-fns-2015.rs:16:5
    |
 LL |     async fn foo() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -44,7 +44,7 @@ LL |     async fn foo() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:18:5
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
    |
 LL |     async fn foo() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -53,7 +53,7 @@ LL |     async fn foo() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:36:9
+  --> $DIR/edition-deny-async-fns-2015.rs:38:9
    |
 LL |         async fn bar() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -62,7 +62,7 @@ LL |         async fn bar() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:26:9
+  --> $DIR/edition-deny-async-fns-2015.rs:28:9
    |
 LL |         async fn foo() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -71,7 +71,7 @@ LL |         async fn foo() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:31:13
+  --> $DIR/edition-deny-async-fns-2015.rs:33:13
    |
 LL |             async fn bar() {}
    |             ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -80,7 +80,7 @@ LL |             async fn bar() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/edition-deny-async-fns-2015.rs:18:5
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
    |
 LL |     async fn foo() {}
    |     -----^^^^^^^^^
diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.next.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.next.stderr
new file mode 100644
index 00000000000..c47b99e657e
--- /dev/null
+++ b/tests/ui/async-await/edition-deny-async-fns-2015.next.stderr
@@ -0,0 +1,98 @@
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:5:1
+   |
+LL | async fn foo() {}
+   | ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:7:12
+   |
+LL | fn baz() { async fn foo() {} }
+   |            ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:9:1
+   |
+LL | async fn async_baz() {
+   | ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:10:5
+   |
+LL |     async fn bar() {}
+   |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:16:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:38:9
+   |
+LL |         async fn bar() {}
+   |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:28:9
+   |
+LL |         async fn foo() {}
+   |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+  --> $DIR/edition-deny-async-fns-2015.rs:33:13
+   |
+LL |             async fn bar() {}
+   |             ^^^^^ to use `async fn`, switch to Rust 2018 or later
+   |
+   = help: pass `--edition 2021` to `rustc`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+   |
+LL |     async fn foo() {}
+   |     -----^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0670, E0706.
+For more information about an error, try `rustc --explain E0670`.
diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.rs b/tests/ui/async-await/edition-deny-async-fns-2015.rs
index 6bd6d879a4a..d4c30dc9d82 100644
--- a/tests/ui/async-await/edition-deny-async-fns-2015.rs
+++ b/tests/ui/async-await/edition-deny-async-fns-2015.rs
@@ -1,4 +1,6 @@
 // edition:2015
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
 
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.current.stderr b/tests/ui/async-await/in-trait/generics-mismatch.current.stderr
new file mode 100644
index 00000000000..be23384e049
--- /dev/null
+++ b/tests/ui/async-await/in-trait/generics-mismatch.current.stderr
@@ -0,0 +1,16 @@
+error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
+  --> $DIR/generics-mismatch.rs:13:18
+   |
+LL | trait Foo {
+   |       ---
+LL |     async fn foo<T>();
+   |                  - expected type parameter
+...
+LL | impl Foo for () {
+   | ---------------
+LL |     async fn foo<const N: usize>() {}
+   |                  ^^^^^^^^^^^^^^ found const parameter of type `usize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.next.stderr b/tests/ui/async-await/in-trait/generics-mismatch.next.stderr
new file mode 100644
index 00000000000..be23384e049
--- /dev/null
+++ b/tests/ui/async-await/in-trait/generics-mismatch.next.stderr
@@ -0,0 +1,16 @@
+error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
+  --> $DIR/generics-mismatch.rs:13:18
+   |
+LL | trait Foo {
+   |       ---
+LL |     async fn foo<T>();
+   |                  - expected type parameter
+...
+LL | impl Foo for () {
+   | ---------------
+LL |     async fn foo<const N: usize>() {}
+   |                  ^^^^^^^^^^^^^^ found const parameter of type `usize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.rs b/tests/ui/async-await/in-trait/generics-mismatch.rs
new file mode 100644
index 00000000000..fc29783c0e3
--- /dev/null
+++ b/tests/ui/async-await/in-trait/generics-mismatch.rs
@@ -0,0 +1,15 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    async fn foo<T>();
+}
+
+impl Foo for () {
+    async fn foo<const N: usize>() {}
+    //~^ ERROR: method `foo` has an incompatible generic parameter for trait `Foo` [E0053]
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.stderr b/tests/ui/async-await/in-trait/generics-mismatch.stderr
new file mode 100644
index 00000000000..3518aa05cec
--- /dev/null
+++ b/tests/ui/async-await/in-trait/generics-mismatch.stderr
@@ -0,0 +1,16 @@
+error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
+  --> $DIR/generics-mismatch.rs:11:18
+   |
+LL | trait Foo {
+   |       ---
+LL |     async fn foo<T>();
+   |                  - expected type parameter
+...
+LL | impl Foo for () {
+   | ---------------
+LL |     async fn foo<const N: usize>() {}
+   |                  ^^^^^^^^^^^^^^ found const parameter of type `usize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr
index b8d83d0f28a..a5efc757156 100644
--- a/tests/ui/async-await/in-trait/return-type-suggestion.stderr
+++ b/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/return-type-suggestion.rs:3:12
+  --> $DIR/return-type-suggestion.rs:5:12
    |
 LL | #![feature(async_fn_in_trait)]
    |            ^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | #![feature(async_fn_in_trait)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0308]: mismatched types
-  --> $DIR/return-type-suggestion.rs:8:9
+  --> $DIR/return-type-suggestion.rs:10:9
    |
 LL |         Ok(())
    |         ^^^^^^- help: consider using a semicolon here: `;`
diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr
new file mode 100644
index 00000000000..a5efc757156
--- /dev/null
+++ b/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr
@@ -0,0 +1,23 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/return-type-suggestion.rs:5:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/return-type-suggestion.rs:10:9
+   |
+LL |         Ok(())
+   |         ^^^^^^- help: consider using a semicolon here: `;`
+   |         |
+   |         expected `()`, found `Result<(), _>`
+   |
+   = note: expected unit type `()`
+                   found enum `Result<(), _>`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.rs b/tests/ui/async-await/in-trait/return-type-suggestion.rs
index 3446761d119..3de66306d9a 100644
--- a/tests/ui/async-await/in-trait/return-type-suggestion.rs
+++ b/tests/ui/async-await/in-trait/return-type-suggestion.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 //~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.full.stderr b/tests/ui/const-generics/const-arg-in-const-arg.full.stderr
index 8672e79b3e8..463a37d7e3d 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.full.stderr
+++ b/tests/ui/const-generics/const-arg-in-const-arg.full.stderr
@@ -1,4 +1,4 @@
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:18:23
    |
 LL |     let _: [u8; faz::<'a>(&())];
@@ -10,7 +10,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:21:23
    |
 LL |     let _: [u8; faz::<'b>(&())];
@@ -22,7 +22,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:41:24
    |
 LL |     let _: Foo<{ faz::<'a>(&()) }>;
@@ -34,7 +34,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:44:24
    |
 LL |     let _: Foo<{ faz::<'b>(&()) }>;
@@ -94,7 +94,7 @@ LL |     let _ = [0; bar::<N>()];
    |
    = help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:30:23
    |
 LL |     let _ = [0; faz::<'a>(&())];
@@ -106,7 +106,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:33:23
    |
 LL |     let _ = [0; faz::<'b>(&())];
@@ -134,7 +134,7 @@ LL |     let _ = Foo::<{ bar::<N>() }>;
    |
    = help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:52:27
    |
 LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
@@ -146,7 +146,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:55:27
    |
 LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
@@ -160,3 +160,4 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
 
 error: aborting due to 16 previous errors
 
+For more information about this error, try `rustc --explain E0794`.
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
index f1353aa9943..a7bd9c62b0e 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -216,7 +216,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
 LL |     let _: [u8; bar::<{ N }>()];
    |                       +   +
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:18:23
    |
 LL |     let _: [u8; faz::<'a>(&())];
@@ -228,7 +228,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:21:23
    |
 LL |     let _: [u8; faz::<'b>(&())];
@@ -251,7 +251,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
 LL |     let _: Foo<{ bar::<{ N }>() }>;
    |                        +   +
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:41:24
    |
 LL |     let _: Foo<{ faz::<'a>(&()) }>;
@@ -263,7 +263,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:44:24
    |
 LL |     let _: Foo<{ faz::<'b>(&()) }>;
@@ -294,7 +294,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
 LL |     let _ = [0; bar::<{ N }>()];
    |                       +   +
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:30:23
    |
 LL |     let _ = [0; faz::<'a>(&())];
@@ -306,7 +306,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:33:23
    |
 LL |     let _ = [0; faz::<'b>(&())];
@@ -329,7 +329,7 @@ help: if this generic argument was intended as a const parameter, surround it wi
 LL |     let _ = Foo::<{ bar::<{ N }>() }>;
    |                           +   +
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:52:27
    |
 LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
@@ -341,7 +341,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/const-arg-in-const-arg.rs:55:27
    |
 LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
@@ -355,5 +355,5 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
 
 error: aborting due to 36 previous errors
 
-Some errors have detailed explanations: E0658, E0747.
+Some errors have detailed explanations: E0658, E0747, E0794.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr
index b5fc9d44d36..3c24eff9ae3 100644
--- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.stderr
+++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/default-body-with-rpit.rs:11:9
+  --> $DIR/default-body-with-rpit.rs:13:9
    |
 LL |         ""
    |         ^^ expected `impl Debug`, got `&'static str`
    |
 note: previous use here
-  --> $DIR/default-body-with-rpit.rs:10:39
+  --> $DIR/default-body-with-rpit.rs:12:39
    |
 LL |       async fn baz(&self) -> impl Debug {
    |  _______________________________________^
@@ -14,7 +14,7 @@ LL | |     }
    | |_____^
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/default-body-with-rpit.rs:10:28
+  --> $DIR/default-body-with-rpit.rs:12:28
    |
 LL |     async fn baz(&self) -> impl Debug {
    |                            ^^^^^^^^^^ cannot resolve opaque type
diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr
new file mode 100644
index 00000000000..3c24eff9ae3
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr
@@ -0,0 +1,24 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/default-body-with-rpit.rs:13:9
+   |
+LL |         ""
+   |         ^^ expected `impl Debug`, got `&'static str`
+   |
+note: previous use here
+  --> $DIR/default-body-with-rpit.rs:12:39
+   |
+LL |       async fn baz(&self) -> impl Debug {
+   |  _______________________________________^
+LL | |         ""
+LL | |     }
+   | |_____^
+
+error[E0720]: cannot resolve opaque type
+  --> $DIR/default-body-with-rpit.rs:12:28
+   |
+LL |     async fn baz(&self) -> impl Debug {
+   |                            ^^^^^^^^^^ cannot resolve opaque type
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs
index 0558d95128f..6bcc7b9ef95 100644
--- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs
+++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs
@@ -1,5 +1,7 @@
 // edition:2021
 // known-bug: #108304
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr
index aa5492d285e..653016cf009 100644
--- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr
+++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `()` doesn't implement `std::fmt::Display`
-  --> $DIR/doesnt-satisfy.rs:9:17
+  --> $DIR/doesnt-satisfy.rs:12:17
    |
 LL |     fn bar() -> () {}
    |                 ^^ `()` cannot be formatted with the default formatter
@@ -7,7 +7,7 @@ LL |     fn bar() -> () {}
    = help: the trait `std::fmt::Display` is not implemented for `()`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
 note: required by a bound in `Foo::bar::{opaque#0}`
-  --> $DIR/doesnt-satisfy.rs:5:22
+  --> $DIR/doesnt-satisfy.rs:8:22
    |
 LL |     fn bar() -> impl std::fmt::Display;
    |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{opaque#0}`
diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr
new file mode 100644
index 00000000000..bbfa089ceef
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `()` doesn't implement `std::fmt::Display`
+  --> $DIR/doesnt-satisfy.rs:12:17
+   |
+LL |     fn bar() -> () {}
+   |                 ^^ `()` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `()`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Foo::{opaque#0}`
+  --> $DIR/doesnt-satisfy.rs:8:22
+   |
+LL |     fn bar() -> impl std::fmt::Display;
+   |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs b/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs
index bb4e0d44f3e..fcd0b51eea4 100644
--- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs
+++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr
index cd42683e022..310edbcb6cd 100644
--- a/tests/ui/impl-trait/in-trait/generics-mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr
@@ -1,5 +1,5 @@
 error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
-  --> $DIR/generics-mismatch.rs:11:12
+  --> $DIR/generics-mismatch.rs:14:12
    |
 LL |     fn bar(&self) -> impl Sized;
    |           - expected 0 type parameters
diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr
new file mode 100644
index 00000000000..310edbcb6cd
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr
@@ -0,0 +1,12 @@
+error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/generics-mismatch.rs:14:12
+   |
+LL |     fn bar(&self) -> impl Sized;
+   |           - expected 0 type parameters
+...
+LL |     fn bar<T>(&self) {}
+   |            ^ found 1 type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.rs b/tests/ui/impl-trait/in-trait/generics-mismatch.rs
index cc0fc720ebb..9259ca193d1 100644
--- a/tests/ui/impl-trait/in-trait/generics-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/generics-mismatch.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/late-bound-lifetimes/issue-80618.rs b/tests/ui/late-bound-lifetimes/issue-80618.rs
new file mode 100644
index 00000000000..6aa8ff461a9
--- /dev/null
+++ b/tests/ui/late-bound-lifetimes/issue-80618.rs
@@ -0,0 +1,8 @@
+fn foo<'a>(x: &'a str) -> &'a str {
+    x
+}
+
+fn main() {
+    let _ = foo::<'static>;
+//~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present [E0794]
+}
diff --git a/tests/ui/late-bound-lifetimes/issue-80618.stderr b/tests/ui/late-bound-lifetimes/issue-80618.stderr
new file mode 100644
index 00000000000..cf7423fc16f
--- /dev/null
+++ b/tests/ui/late-bound-lifetimes/issue-80618.stderr
@@ -0,0 +1,15 @@
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/issue-80618.rs:6:19
+   |
+LL |     let _ = foo::<'static>;
+   |                   ^^^^^^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/issue-80618.rs:1:8
+   |
+LL | fn foo<'a>(x: &'a str) -> &'a str {
+   |        ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0794`.
diff --git a/tests/ui/methods/method-call-lifetime-args-fail.stderr b/tests/ui/methods/method-call-lifetime-args-fail.stderr
index 34526256f99..645d8b8d14a 100644
--- a/tests/ui/methods/method-call-lifetime-args-fail.stderr
+++ b/tests/ui/methods/method-call-lifetime-args-fail.stderr
@@ -30,7 +30,7 @@ note: method defined here, with 2 lifetime parameters: `'a`, `'b`
 LL |     fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
    |        ^^^^^ --  --
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:27:15
    |
 LL |     S::late::<'static>(S, &0, &0);
@@ -42,7 +42,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
    |             ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:29:15
    |
 LL |     S::late::<'static, 'static>(S, &0, &0);
@@ -54,7 +54,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
    |             ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:31:15
    |
 LL |     S::late::<'static, 'static, 'static>(S, &0, &0);
@@ -66,7 +66,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
    |             ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:34:21
    |
 LL |     S::late_early::<'static, 'static>(S, &0);
@@ -78,7 +78,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} }
    |                   ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:36:21
    |
 LL |     S::late_early::<'static, 'static, 'static>(S, &0);
@@ -90,7 +90,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} }
    |                   ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:40:24
    |
 LL |     S::late_implicit::<'static>(S, &0, &0);
@@ -102,7 +102,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit(self, _: &u8, _: &u8) {}
    |                               ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:42:24
    |
 LL |     S::late_implicit::<'static, 'static>(S, &0, &0);
@@ -114,7 +114,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit(self, _: &u8, _: &u8) {}
    |                               ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:44:24
    |
 LL |     S::late_implicit::<'static, 'static, 'static>(S, &0, &0);
@@ -126,7 +126,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit(self, _: &u8, _: &u8) {}
    |                               ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:47:30
    |
 LL |     S::late_implicit_early::<'static, 'static>(S, &0);
@@ -138,7 +138,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} }
    |                                         ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:49:30
    |
 LL |     S::late_implicit_early::<'static, 'static, 'static>(S, &0);
@@ -150,7 +150,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} }
    |                                         ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:52:35
    |
 LL |     S::late_implicit_self_early::<'static, 'static>(&S);
@@ -162,7 +162,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} }
    |                                     ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:54:35
    |
 LL |     S::late_implicit_self_early::<'static, 'static, 'static>(&S);
@@ -174,7 +174,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} }
    |                                     ^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:57:28
    |
 LL |     S::late_unused_early::<'static, 'static>(S);
@@ -186,7 +186,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} }
    |                          ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-fail.rs:59:28
    |
 LL |     S::late_unused_early::<'static, 'static, 'static>(S);
@@ -232,4 +232,5 @@ LL |     fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
 
 error: aborting due to 18 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0794.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/methods/method-call-lifetime-args.stderr b/tests/ui/methods/method-call-lifetime-args.stderr
index 64ae79e9bb2..b215d583217 100644
--- a/tests/ui/methods/method-call-lifetime-args.stderr
+++ b/tests/ui/methods/method-call-lifetime-args.stderr
@@ -1,4 +1,4 @@
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args.rs:9:15
    |
 LL |     S::late::<'static>(S, &0, &0);
@@ -10,7 +10,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
    |             ^^
 
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args.rs:11:24
    |
 LL |     S::late_implicit::<'static>(S, &0, &0);
@@ -24,3 +24,4 @@ LL |     fn late_implicit(self, _: &u8, _: &u8) {}
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0794`.