diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2b6e96b467e35..23d3e71424b2b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -41,16 +41,24 @@ jobs:
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
       CACHE_DOMAIN: ci-caches.rust-lang.org
     if: "github.event_name == 'pull_request'"
+    continue-on-error: "${{ matrix.tidy }}"
     strategy:
       matrix:
         include:
           - name: mingw-check
+            tidy: false
+            os: ubuntu-20.04-xl
+            env: {}
+          - name: mingw-check-tidy
+            tidy: true
             os: ubuntu-20.04-xl
             env: {}
           - name: x86_64-gnu-llvm-13
+            tidy: false
             os: ubuntu-20.04-xl
             env: {}
           - name: x86_64-gnu-tools
+            tidy: false
             env:
               CI_ONLY_WHEN_SUBMODULES_CHANGED: 1
             os: ubuntu-20.04-xl
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index cff72048ead08..978aff511bfa7 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -637,7 +637,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         self.set_debug_loc(bx, terminator.source_info);
 
         // Obtain the panic entry point.
-        let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicNoUnwind);
+        let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicCannotUnwind);
 
         // Codegen the actual panic invoke/call.
         let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &[], None, None, &[], false);
@@ -698,11 +698,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     })
                 });
                 let msg = bx.const_str(&msg_str);
-                let location = self.get_caller_location(bx, source_info).immediate();
 
                 // Obtain the panic entry point.
                 let (fn_abi, llfn) =
-                    common::build_langcall(bx, Some(source_info.span), LangItem::Panic);
+                    common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind);
 
                 // Codegen the actual panic invoke/call.
                 helper.do_call(
@@ -710,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     bx,
                     fn_abi,
                     llfn,
-                    &[msg.0, msg.1, location],
+                    &[msg.0, msg.1],
                     target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)),
                     cleanup,
                     &[],
@@ -1665,7 +1664,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let llpersonality = self.cx.eh_personality();
             bx.cleanup_landing_pad(llpersonality);
 
-            let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
+            let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicCannotUnwind);
             let fn_ty = bx.fn_decl_backend_type(&fn_abi);
 
             let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], None);
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 038509031b180..3474fab34f00b 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -146,7 +146,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
 }
 
 language_item_table! {
-//  Variant name,            Name,                     Method name,                Target                  Generic requirements;
+//  Variant name,            Name,                     Getter method name,         Target                  Generic requirements;
     Sized,                   sym::sized,               sized_trait,                Target::Trait,          GenericRequirement::Exact(0);
     Unsize,                  sym::unsize,              unsize_trait,               Target::Trait,          GenericRequirement::Minimum(1);
     /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
@@ -232,6 +232,7 @@ language_item_table! {
     // is required to define it somewhere. Additionally, there are restrictions on crates that use
     // a weak lang item, but do not have it defined.
     Panic,                   sym::panic,               panic_fn,                   Target::Fn,             GenericRequirement::Exact(0);
+    PanicNounwind,           sym::panic_nounwind,      panic_nounwind,             Target::Fn,             GenericRequirement::Exact(0);
     PanicFmt,                sym::panic_fmt,           panic_fmt,                  Target::Fn,             GenericRequirement::None;
     PanicDisplay,            sym::panic_display,       panic_display,              Target::Fn,             GenericRequirement::None;
     ConstPanicFmt,           sym::const_panic_fmt,     const_panic_fmt,            Target::Fn,             GenericRequirement::None;
@@ -239,7 +240,7 @@ language_item_table! {
     PanicInfo,               sym::panic_info,          panic_info,                 Target::Struct,         GenericRequirement::None;
     PanicLocation,           sym::panic_location,      panic_location,             Target::Struct,         GenericRequirement::None;
     PanicImpl,               sym::panic_impl,          panic_impl,                 Target::Fn,             GenericRequirement::None;
-    PanicNoUnwind,           sym::panic_no_unwind,     panic_no_unwind,            Target::Fn,             GenericRequirement::Exact(0);
+    PanicCannotUnwind,       sym::panic_cannot_unwind, panic_cannot_unwind,        Target::Fn,             GenericRequirement::Exact(0);
     /// libstd panic entry point. Necessary for const eval to be able to catch it
     BeginPanic,              sym::begin_panic,         begin_panic_fn,             Target::Fn,             GenericRequirement::None;
 
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 4ec71a78a0031..af14ee08a9981 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -399,6 +399,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ty::FnPtr(sig) => (sig, None),
             _ => {
+                for arg in arg_exprs {
+                    self.check_expr(arg);
+                }
+
                 if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &callee_expr.kind
                     && let [segment] = path.segments
                     && let Some(mut diag) = self
@@ -486,7 +490,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Expectation<'tcx>,
     ) -> Option<Ty<'tcx>> {
         if let [callee_expr, rest @ ..] = arg_exprs {
-            let callee_ty = self.check_expr(callee_expr);
+            let callee_ty = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr)?;
+
             // First, do a probe with `IsSuggestion(true)` to avoid emitting
             // any strange errors. If it's successful, then we'll do a true
             // method lookup.
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 15546092e41a2..dda5f4bac4289 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -1011,11 +1011,7 @@ impl CrateError {
                 sess.emit_err(SymbolConflictsOthers { span, crate_name: root_name });
             }
             CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
-                sess.emit_err(StableCrateIdCollision {
-                    span,
-                    crate_name0: crate_name0,
-                    crate_name1: crate_name1,
-                });
+                sess.emit_err(StableCrateIdCollision { span, crate_name0, crate_name1 });
             }
             CrateError::DlOpen(s) | CrateError::DlSym(s) => {
                 sess.emit_err(DlError { span, err: s });
@@ -1074,7 +1070,7 @@ impl CrateError {
                     }
                     sess.emit_err(NoCrateWithTriple {
                         span,
-                        crate_name: crate_name,
+                        crate_name,
                         locator_triple: locator.triple.triple(),
                         add_info,
                         found_crates,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 4370d4bd758d2..99d8225a4c391 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -78,10 +78,6 @@ pub(crate) struct CrateMetadata {
     blob: MetadataBlob,
 
     // --- Some data pre-decoded from the metadata blob, usually for performance ---
-    /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
-    /// lifetime is only used behind `LazyValue`, `LazyArray`, or `LazyTable`, and therefore acts like a
-    /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
-    /// is being used to decode those values.
     root: CrateRoot,
     /// Trait impl data.
     /// FIXME: Used only from queries and can use query cache,
@@ -688,10 +684,10 @@ impl MetadataBlob {
     pub(crate) fn get_root(&self) -> CrateRoot {
         let slice = &self.blob()[..];
         let offset = METADATA_HEADER.len();
-        let pos = (((slice[offset + 0] as u32) << 24)
-            | ((slice[offset + 1] as u32) << 16)
-            | ((slice[offset + 2] as u32) << 8)
-            | ((slice[offset + 3] as u32) << 0)) as usize;
+
+        let pos_bytes = slice[offset..][..4].try_into().unwrap();
+        let pos = u32::from_be_bytes(pos_bytes) as usize;
+
         LazyValue::<CrateRoot>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
     }
 
@@ -702,16 +698,14 @@ impl MetadataBlob {
         writeln!(out, "hash {} stable_crate_id {:?}", root.hash, root.stable_crate_id)?;
         writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
         writeln!(out, "=External Dependencies=")?;
+
         for (i, dep) in root.crate_deps.decode(self).enumerate() {
+            let CrateDep { name, extra_filename, hash, host_hash, kind } = dep;
+            let number = i + 1;
+
             writeln!(
                 out,
-                "{} {}{} hash {} host_hash {:?} kind {:?}",
-                i + 1,
-                dep.name,
-                dep.extra_filename,
-                dep.hash,
-                dep.host_hash,
-                dep.kind
+                "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?}"
             )?;
         }
         write!(out, "\n")?;
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 6b60577c9023f..26a41f633fffa 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -416,11 +416,6 @@ struct VariantData {
     is_non_exhaustive: bool,
 }
 
-#[derive(TyEncodable, TyDecodable)]
-struct GeneratorData<'tcx> {
-    layout: mir::GeneratorLayout<'tcx>,
-}
-
 // Tags used for encoding Spans:
 const TAG_VALID_SPAN_LOCAL: u8 = 0;
 const TAG_VALID_SPAN_FOREIGN: u8 = 1;
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index deeeb9af4eb92..59cc500a99da7 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -843,7 +843,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
             mir::TerminatorKind::Abort { .. } => {
                 let instance = Instance::mono(
                     tcx,
-                    tcx.require_lang_item(LangItem::PanicNoUnwind, Some(source)),
+                    tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)),
                 );
                 if should_codegen_locally(tcx, &instance) {
                     self.output.push(create_fn_mono_item(tcx, instance, source));
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index e802663471341..90f654c68ecbf 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1041,6 +1041,7 @@ symbols! {
         panic_2021,
         panic_abort,
         panic_bounds_check,
+        panic_cannot_unwind,
         panic_display,
         panic_fmt,
         panic_handler,
@@ -1048,7 +1049,7 @@ symbols! {
         panic_implementation,
         panic_info,
         panic_location,
-        panic_no_unwind,
+        panic_nounwind,
         panic_runtime,
         panic_str,
         panic_unwind,
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index a521905a9e735..6eeaef5ab0129 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2281,7 +2281,7 @@ macro_rules! assert_unsafe_precondition {
             fn runtime$(<$($tt)*>)?($($i:$ty),*) {
                 if !$e {
                     // don't unwind to reduce impact on code size
-                    ::core::panicking::panic_str_nounwind(
+                    ::core::panicking::panic_nounwind(
                         concat!("unsafe precondition(s) violated: ", $name)
                     );
                 }
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index a704a00faaafa..9fce78d076bf3 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -64,12 +64,13 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
     unsafe { panic_impl(&pi) }
 }
 
-/// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize.
-/// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed.
+/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize.
+/// (No `fmt` variant as a `fmt::Arguments` needs more space to be passed.)
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(bootstrap), lang = "panic_nounwind")] // needed by codegen for non-unwinding panics
 #[rustc_nounwind]
-pub fn panic_str_nounwind(msg: &'static str) -> ! {
+pub fn panic_nounwind(msg: &'static str) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
         super::intrinsics::abort()
     }
@@ -153,10 +154,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 /// any extra arguments (including those synthesized by track_caller).
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function
+#[cfg_attr(bootstrap, lang = "panic_no_unwind")] // needed by codegen for panic in nounwind function
+#[cfg_attr(not(bootstrap), lang = "panic_cannot_unwind")] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
-fn panic_no_unwind() -> ! {
-    panic_str_nounwind("panic in a function that cannot unwind")
+fn panic_cannot_unwind() -> ! {
+    panic_nounwind("panic in a function that cannot unwind")
 }
 
 /// This function is used instead of panic_fmt in const eval.
diff --git a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile b/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
new file mode 100644
index 0000000000000..78fee152eb9d4
--- /dev/null
+++ b/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
@@ -0,0 +1,36 @@
+FROM ubuntu:18.04
+# FIXME: when bumping the version, remove the Python 3.6-specific changes in
+# the reuse-requirements.in file, regenerate reuse-requirements.txt and remove
+# this comment.
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  ninja-build \
+  file \
+  curl \
+  ca-certificates \
+  python3 \
+  python3-pip \
+  python3-pkg-resources \
+  git \
+  cmake \
+  sudo \
+  gdb \
+  xz-utils \
+  libssl-dev \
+  pkg-config \
+  mingw-w64 \
+  && rm -rf /var/lib/apt/lists/*
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
+RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt
+
+COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
+COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
+
+ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
+ENV SCRIPT python3 ../x.py test --stage 0 src/tools/tidy
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 9e2568af13f68..adf6bb4b37752 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -40,7 +40,6 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
-           python3 ../x.py test --stage 0 src/tools/tidy && \
            python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu --all-targets && \
            python3 ../x.py build --stage 0 src/tools/build-manifest && \
            python3 ../x.py test --stage 0 src/tools/compiletest && \
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index d1ba46ad30de6..d33396dcc80fe 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -287,19 +287,27 @@ jobs:
     env:
       <<: [*shared-ci-variables, *public-variables]
     if: github.event_name == 'pull_request'
+    continue-on-error: ${{ matrix.tidy }}
     strategy:
       matrix:
         include:
           - name: mingw-check
             <<: *job-linux-xl
+            tidy: false
+
+          - name: mingw-check-tidy
+            <<: *job-linux-xl
+            tidy: true
 
           - name: x86_64-gnu-llvm-13
             <<: *job-linux-xl
+            tidy: false
 
           - name: x86_64-gnu-tools
+            <<: *job-linux-xl
+            tidy: false
             env:
               CI_ONLY_WHEN_SUBMODULES_CHANGED: 1
-            <<: *job-linux-xl
 
   auto:
     permissions:
diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh
index be7de3ebaf571..2a3086338b4bf 100755
--- a/src/etc/pre-push.sh
+++ b/src/etc/pre-push.sh
@@ -10,16 +10,8 @@ set -Eeuo pipefail
 # https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570
 unset GIT_DIR
 ROOT_DIR="$(git rev-parse --show-toplevel)"
-COMMAND="$ROOT_DIR/x.py test tidy"
 
-if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
-  COMMAND="python $COMMAND"
-elif ! command -v python &> /dev/null; then
-  COMMAND="python3 $COMMAND"
-fi
-
-echo "Running pre-push script '$COMMAND'"
+echo "Running pre-push script $ROOT_DIR/x test tidy"
 
 cd "$ROOT_DIR"
-
-$COMMAND
+./x test tidy
diff --git a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
index 34fd401f9e42b..ea5bae18e2337 100644
--- a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
+++ b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
@@ -10,7 +10,7 @@
 #[no_mangle]
 pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() {
     // Handle both legacy and v0 symbol mangling.
-    // CHECK: call void @{{.*core9panicking15panic_no_unwind}}
+    // CHECK: call void @{{.*core9panicking19panic_cannot_unwind}}
     may_unwind();
 }
 
diff --git a/src/test/codegen/unwind-and-panic-abort.rs b/src/test/codegen/unwind-and-panic-abort.rs
index b370191bf8c82..e43e73b96b996 100644
--- a/src/test/codegen/unwind-and-panic-abort.rs
+++ b/src/test/codegen/unwind-and-panic-abort.rs
@@ -10,7 +10,7 @@ extern "C-unwind" {
 // CHECK: Function Attrs:{{.*}}nounwind
 // CHECK-NEXT: define{{.*}}void @foo
 // Handle both legacy and v0 symbol mangling.
-// CHECK: call void @{{.*core9panicking15panic_no_unwind}}
+// CHECK: call void @{{.*core9panicking19panic_cannot_unwind}}
 #[no_mangle]
 pub unsafe extern "C" fn foo() {
     bar();
diff --git a/src/test/ui/issues/issue-3044.rs b/src/test/ui/fn/issue-3044.rs
similarity index 100%
rename from src/test/ui/issues/issue-3044.rs
rename to src/test/ui/fn/issue-3044.rs
diff --git a/src/test/ui/issues/issue-3044.stderr b/src/test/ui/fn/issue-3044.stderr
similarity index 100%
rename from src/test/ui/issues/issue-3044.stderr
rename to src/test/ui/fn/issue-3044.stderr
diff --git a/src/test/ui/issues/issue-3904.rs b/src/test/ui/fn/issue-3904.rs
similarity index 100%
rename from src/test/ui/issues/issue-3904.rs
rename to src/test/ui/fn/issue-3904.rs
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index ec3860a322fc5..142c0fc81b4ab 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -1,7 +1,5 @@
 // run-pass
-// needs-unwind
-// revisions: mir thir strict
-// [thir]compile-flags: -Zthir-unsafeck
+// revisions: default strict
 // [strict]compile-flags: -Zstrict-init-checks
 // ignore-tidy-linelength
 
@@ -12,7 +10,6 @@
 
 use std::{
     mem::{self, MaybeUninit, ManuallyDrop},
-    panic,
     ptr::NonNull,
     num,
 };
@@ -70,21 +67,42 @@ enum ZeroIsValid {
 }
 
 #[track_caller]
-fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
-    let err = panic::catch_unwind(op).err();
-    assert_eq!(
-        err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
-        Some(&msg)
-    );
+fn test_panic_msg<T, F: (FnOnce() -> T) + 'static>(op: F, msg: &str) {
+    use std::{panic, env, process};
+
+    // The tricky part is that we can't just run `op`, as that would *abort* the process.
+    // So instead, we reinvoke this process with the caller location as argument.
+    // For the purpose of this test, the line number is unique enough.
+    // If we are running in such a re-invocation, we skip all the tests *except* for the one with that type name.
+    let our_loc = panic::Location::caller().line().to_string();
+    let mut args = env::args();
+    let this = args.next().unwrap();
+    if let Some(loc) = args.next() {
+        if loc == our_loc {
+            op();
+            panic!("we did not abort");
+        } else {
+            // Nothing, we are running another test.
+        }
+    } else {
+        // Invoke new process for actual test, and check result.
+        let mut cmd = process::Command::new(this);
+        cmd.arg(our_loc);
+        let res = cmd.output().unwrap();
+        assert!(!res.status.success(), "test did not fail");
+        let stderr = String::from_utf8_lossy(&res.stderr);
+        assert!(stderr.contains(msg), "test did not contain expected output: looking for {:?}, output:\n{}", msg, stderr);
+    }
 }
 
 #[track_caller]
-fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
-    let err = panic::catch_unwind(op).err();
-    assert_eq!(
-        err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
-        if cfg!(strict) { Some(&msg) } else { None },
-    );
+fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + 'static, msg: &str) {
+    if !cfg!(strict) {
+        // Just run it.
+        op();
+    } else {
+        test_panic_msg(op, msg);
+    }
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-6470.rs b/src/test/ui/issues/issue-6470.rs
deleted file mode 100644
index 8c6192a59dba2..0000000000000
--- a/src/test/ui/issues/issue-6470.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// build-pass
-#![allow(dead_code)]
-#![allow(improper_ctypes)]
-// pretty-expanded FIXME #23616
-#![allow(non_snake_case)]
-
-pub mod Bar {
-    pub struct Foo {
-        v: isize,
-    }
-
-    extern "C" {
-        pub fn foo(v: *const Foo) -> Foo;
-    }
-}
-
-pub fn main() {}
diff --git a/src/test/ui/issues/issue-36381.rs b/src/test/ui/late-bound-lifetimes/issue-36381.rs
similarity index 100%
rename from src/test/ui/issues/issue-36381.rs
rename to src/test/ui/late-bound-lifetimes/issue-36381.rs
diff --git a/src/test/ui/issues/issue-25385.rs b/src/test/ui/macros/issue-25385.rs
similarity index 100%
rename from src/test/ui/issues/issue-25385.rs
rename to src/test/ui/macros/issue-25385.rs
diff --git a/src/test/ui/issues/issue-25385.stderr b/src/test/ui/macros/issue-25385.stderr
similarity index 100%
rename from src/test/ui/issues/issue-25385.stderr
rename to src/test/ui/macros/issue-25385.stderr
diff --git a/src/test/ui/issues/issue-5530.rs b/src/test/ui/match/issue-5530.rs
similarity index 100%
rename from src/test/ui/issues/issue-5530.rs
rename to src/test/ui/match/issue-5530.rs
diff --git a/src/test/ui/issues/auxiliary/issue-30535.rs b/src/test/ui/resolve/auxiliary/issue-30535.rs
similarity index 100%
rename from src/test/ui/issues/auxiliary/issue-30535.rs
rename to src/test/ui/resolve/auxiliary/issue-30535.rs
diff --git a/src/test/ui/issues/issue-30535.rs b/src/test/ui/resolve/issue-30535.rs
similarity index 100%
rename from src/test/ui/issues/issue-30535.rs
rename to src/test/ui/resolve/issue-30535.rs
diff --git a/src/test/ui/issues/issue-30535.stderr b/src/test/ui/resolve/issue-30535.stderr
similarity index 100%
rename from src/test/ui/issues/issue-30535.stderr
rename to src/test/ui/resolve/issue-30535.stderr
diff --git a/src/test/ui/issues/issue-39559-2.rs b/src/test/ui/resolve/issue-39559-2.rs
similarity index 100%
rename from src/test/ui/issues/issue-39559-2.rs
rename to src/test/ui/resolve/issue-39559-2.rs
diff --git a/src/test/ui/issues/issue-39559-2.stderr b/src/test/ui/resolve/issue-39559-2.stderr
similarity index 100%
rename from src/test/ui/issues/issue-39559-2.stderr
rename to src/test/ui/resolve/issue-39559-2.stderr
diff --git a/src/test/ui/issues/issue-39559.rs b/src/test/ui/resolve/issue-39559.rs
similarity index 100%
rename from src/test/ui/issues/issue-39559.rs
rename to src/test/ui/resolve/issue-39559.rs
diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/resolve/issue-39559.stderr
similarity index 100%
rename from src/test/ui/issues/issue-39559.stderr
rename to src/test/ui/resolve/issue-39559.stderr
diff --git a/src/test/ui/issues/issue-18118-2.rs b/src/test/ui/static/issue-18118-2.rs
similarity index 100%
rename from src/test/ui/issues/issue-18118-2.rs
rename to src/test/ui/static/issue-18118-2.rs
diff --git a/src/test/ui/issues/issue-18118-2.stderr b/src/test/ui/static/issue-18118-2.stderr
similarity index 100%
rename from src/test/ui/issues/issue-18118-2.stderr
rename to src/test/ui/static/issue-18118-2.stderr
diff --git a/src/test/ui/issues/issue-18118.rs b/src/test/ui/static/issue-18118.rs
similarity index 100%
rename from src/test/ui/issues/issue-18118.rs
rename to src/test/ui/static/issue-18118.rs
diff --git a/src/test/ui/issues/issue-18118.stderr b/src/test/ui/static/issue-18118.stderr
similarity index 100%
rename from src/test/ui/issues/issue-18118.stderr
rename to src/test/ui/static/issue-18118.stderr
diff --git a/src/test/ui/suggestions/fn-to-method-deeply-nested.rs b/src/test/ui/suggestions/fn-to-method-deeply-nested.rs
new file mode 100644
index 0000000000000..58ee3d6409a7e
--- /dev/null
+++ b/src/test/ui/suggestions/fn-to-method-deeply-nested.rs
@@ -0,0 +1,13 @@
+fn main() -> Result<(), ()> {
+    a(b(c(d(e(
+        //~^ ERROR cannot find function `a` in this scope
+        //~| ERROR cannot find function `b` in this scope
+        //~| ERROR cannot find function `c` in this scope
+        //~| ERROR cannot find function `d` in this scope
+        //~| ERROR cannot find function `e` in this scope
+        z????????????????????????????????????????????????????????????????????????????????????????
+        ?????????????????????????????????????????????????????????????????????????????????????????
+        ??????????????????????????????????????????????????????????????????
+        //~^^^ ERROR cannot find value `z` in this scope
+    )))))
+}
diff --git a/src/test/ui/suggestions/fn-to-method-deeply-nested.stderr b/src/test/ui/suggestions/fn-to-method-deeply-nested.stderr
new file mode 100644
index 0000000000000..ce813ea7abae8
--- /dev/null
+++ b/src/test/ui/suggestions/fn-to-method-deeply-nested.stderr
@@ -0,0 +1,39 @@
+error[E0425]: cannot find value `z` in this scope
+  --> $DIR/fn-to-method-deeply-nested.rs:8:9
+   |
+LL |         z????????????????????????????????????????????????????????????????????????????????????????
+   |         ^ not found in this scope
+
+error[E0425]: cannot find function `e` in this scope
+  --> $DIR/fn-to-method-deeply-nested.rs:2:13
+   |
+LL |     a(b(c(d(e(
+   |             ^ not found in this scope
+
+error[E0425]: cannot find function `d` in this scope
+  --> $DIR/fn-to-method-deeply-nested.rs:2:11
+   |
+LL |     a(b(c(d(e(
+   |           ^ not found in this scope
+
+error[E0425]: cannot find function `c` in this scope
+  --> $DIR/fn-to-method-deeply-nested.rs:2:9
+   |
+LL |     a(b(c(d(e(
+   |         ^ not found in this scope
+
+error[E0425]: cannot find function `b` in this scope
+  --> $DIR/fn-to-method-deeply-nested.rs:2:7
+   |
+LL |     a(b(c(d(e(
+   |       ^ not found in this scope
+
+error[E0425]: cannot find function `a` in this scope
+  --> $DIR/fn-to-method-deeply-nested.rs:2:5
+   |
+LL |     a(b(c(d(e(
+   |     ^ not found in this scope
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-52557.rs b/src/test/ui/test-attrs/issue-52557.rs
similarity index 100%
rename from src/test/ui/issues/issue-52557.rs
rename to src/test/ui/test-attrs/issue-52557.rs
diff --git a/src/test/ui/typeck/check-args-on-fn-err-2.rs b/src/test/ui/typeck/check-args-on-fn-err-2.rs
new file mode 100644
index 0000000000000..af57dbe33177d
--- /dev/null
+++ b/src/test/ui/typeck/check-args-on-fn-err-2.rs
@@ -0,0 +1,5 @@
+fn main() {
+    a((), 1i32 == 2u32);
+    //~^ ERROR cannot find function `a` in this scope
+    //~| ERROR mismatched types
+}
diff --git a/src/test/ui/typeck/check-args-on-fn-err-2.stderr b/src/test/ui/typeck/check-args-on-fn-err-2.stderr
new file mode 100644
index 0000000000000..301bb88dbacf6
--- /dev/null
+++ b/src/test/ui/typeck/check-args-on-fn-err-2.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/check-args-on-fn-err-2.rs:2:19
+   |
+LL |     a((), 1i32 == 2u32);
+   |           ----    ^^^^ expected `i32`, found `u32`
+   |           |
+   |           expected because this is `i32`
+   |
+help: change the type of the numeric literal from `u32` to `i32`
+   |
+LL |     a((), 1i32 == 2i32);
+   |                    ~~~
+
+error[E0425]: cannot find function `a` in this scope
+  --> $DIR/check-args-on-fn-err-2.rs:2:5
+   |
+LL |     a((), 1i32 == 2u32);
+   |     ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/check-args-on-fn-err.rs b/src/test/ui/typeck/check-args-on-fn-err.rs
new file mode 100644
index 0000000000000..04b98ddd95295
--- /dev/null
+++ b/src/test/ui/typeck/check-args-on-fn-err.rs
@@ -0,0 +1,6 @@
+fn main() {
+    unknown(1, |glyf| {
+        //~^ ERROR: cannot find function `unknown` in this scope
+        let actual = glyf;
+    });
+}
diff --git a/src/test/ui/typeck/check-args-on-fn-err.stderr b/src/test/ui/typeck/check-args-on-fn-err.stderr
new file mode 100644
index 0000000000000..864d33e0e93bb
--- /dev/null
+++ b/src/test/ui/typeck/check-args-on-fn-err.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find function `unknown` in this scope
+  --> $DIR/check-args-on-fn-err.rs:2:5
+   |
+LL |     unknown(1, |glyf| {
+   |     ^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-22375.rs b/src/test/ui/typeck/issue-22375.rs
similarity index 100%
rename from src/test/ui/issues/issue-22375.rs
rename to src/test/ui/typeck/issue-22375.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 19e2528bb240a..f746bdeffd7ca 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -10,7 +10,7 @@ use std::path::Path;
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
 const ROOT_ENTRY_LIMIT: usize = 939;
-const ISSUES_ENTRY_LIMIT: usize = 2040;
+const ISSUES_ENTRY_LIMIT: usize = 2020;
 
 fn check_entries(path: &Path, bad: &mut bool) {
     for dir in Walk::new(&path.join("test/ui")) {