about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-11-02 04:27:48 +0000
committerbors <bors@rust-lang.org>2022-11-02 04:27:48 +0000
commita876a4df32b402e3886cd9f2af02cff3dd8e21c8 (patch)
treec41889bbbcbce1d27875da5943665f2ad35006cd /src
parent11ebe6512b4c77633c59f8dcdd421df3b79d1a9f (diff)
parentc2affd504993072bdb7e04ade9816a5c88ce90e5 (diff)
downloadrust-a876a4df32b402e3886cd9f2af02cff3dd8e21c8.tar.gz
rust-a876a4df32b402e3886cd9f2af02cff3dd8e21c8.zip
Auto merge of #103857 - Manishearth:rollup-709fui6, r=Manishearth
Rollup of 8 pull requests

Successful merges:

 - #103072 (compiletest: set the dylib path when gathering target cfg)
 - #103084 (Derive `Eq` and `Hash` for `ControlFlow`)
 - #103575 (Change #[suggestion_*] attributes to use style="...")
 - #103637 (Use stdio in UWP apps)
 - #103638 (Add `multivalue` target feature to WASM target)
 - #103781 (Detect unused files in `src/test/mir-opt` and error on them in tidy.)
 - #103837 (Migrate sidebar-links-color GUI test to functions)
 - #103839 (Print valid `--print` requests if request is invalid)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/builder.rs1
-rw-r--r--src/bootstrap/check.rs1
-rw-r--r--src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff72
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff106
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff85
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir83
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir58
-rw-r--r--src/test/run-make/valid-print-requests/Makefile4
-rw-r--r--src/test/run-make/valid-print-requests/valid-print-requests.stderr2
-rw-r--r--src/test/rustdoc-gui/sidebar-links-color.goml386
-rw-r--r--src/test/rustdoc-gui/theme-in-history.goml1
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs37
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr46
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs144
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr80
-rw-r--r--src/tools/compiletest/Cargo.toml1
-rw-r--r--src/tools/compiletest/src/common.rs20
-rw-r--r--src/tools/compiletest/src/runtest.rs157
-rw-r--r--src/tools/compiletest/src/util.rs23
-rw-r--r--src/tools/miropt-test-tools/Cargo.toml7
-rw-r--r--src/tools/miropt-test-tools/src/lib.rs70
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs1
-rw-r--r--src/tools/tidy/src/mir_opt_tests.rs37
25 files changed, 592 insertions, 832 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index c8285c85d03..6de37463633 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -622,6 +622,7 @@ impl<'a> Builder<'a> {
                 check::Clippy,
                 check::Miri,
                 check::CargoMiri,
+                check::MiroptTestTools,
                 check::Rls,
                 check::RustAnalyzer,
                 check::Rustfmt,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 4450dd7e80f..2e1bd8d6d1f 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -460,6 +460,7 @@ tool_check_step!(Miri, "src/tools/miri", SourceType::InTree);
 tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree);
 tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
 tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
+tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree);
 
 tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
 
diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
deleted file mode 100644
index c3e503bf2c6..00000000000
--- a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // MIR for `try_identity` before DestinationPropagation
-+ // MIR for `try_identity` after DestinationPropagation
-  
-  fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18
-      let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57
-      let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10
-      let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-      let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-      let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9
-      scope 1 {
-          debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10
-      }
-      scope 2 {
-          debug err => _6;                 // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15
-          scope 3 {
-              scope 7 {
-                  debug t => _9;           // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
-              }
-              scope 8 {
-                  debug v => _8;           // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
-                  let mut _12: i32;        // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15
-              }
-          }
-      }
-      scope 4 {
-          debug val => _10;                // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15
-          scope 5 {
-          }
-      }
-      scope 6 {
--         debug self => _4;                // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-+         debug self => _0;                // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:7:9: 7:10
--         StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
--         StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
--         _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
--         _3 = move _4;                    // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
--         StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
--         _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-+         _0 = _1;                         // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-+         nop;                             // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-+         _5 = discriminant(_0);           // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-          goto -> bb1;                     // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      }
-  
-      bb1: {
--         _0 = move _3;                    // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
--         StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:9:1: 9:2
-          goto -> bb2;                     // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
-      }
-  
-      bb2: {
-          return;                          // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
deleted file mode 100644
index 83b91309be3..00000000000
--- a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
+++ /dev/null
@@ -1,106 +0,0 @@
-- // MIR for `try_identity` before DestinationPropagation
-+ // MIR for `try_identity` after DestinationPropagation
-  
-  fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-      let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-      let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-      let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-      let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-      let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-      let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
-      scope 1 {
--         debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-+         debug y => ((_0 as Ok).0: u32);  // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-      }
-      scope 2 {
-          debug e => _6;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-          scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-              debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          }
-          scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-              debug e => _8;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-          }
-      }
-      scope 3 {
--         debug v => _10;                  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-+         debug v => ((_0 as Ok).0: u32);  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-      }
-      scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
--         debug r => _4;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-+         debug r => _3;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-      }
-  
-      bb0: {
--         StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
--         StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
--         StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
--         _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
--         _3 = move _4;                    // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
--         StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+         _3 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+         nop;                             // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-          _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-          switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-      }
-  
-      bb1: {
--         StorageLive(_10);                // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
--         _10 = ((_3 as Ok).0: u32);       // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
--         _2 = _10;                        // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
--         StorageDead(_10);                // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
--         StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
--         StorageLive(_11);                // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
--         _11 = _2;                        // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-+         ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-+         nop;                             // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-          Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
--         ((_0 as Ok).0: u32) = move _11;  // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
--         StorageDead(_11);                // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
--         StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      }
-  
-      bb3: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          nop;                             // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          StorageLive(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-          StorageLive(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          nop;                             // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          nop;                             // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-          nop;                             // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
-          Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          StorageDead(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-          StorageDead(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
--         StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
--         StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
deleted file mode 100644
index e025ae7c551..00000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,85 +0,0 @@
-- // MIR for `try_identity` before SimplifyArmIdentity
-+ // MIR for `try_identity` after SimplifyArmIdentity
-  
-  fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-      let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-      let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-      let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-      let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-      let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-      let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
-      scope 1 {
-          debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-      }
-      scope 2 {
-          debug e => _6;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-          scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-              debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          }
-          scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-              debug e => _8;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-          }
-      }
-      scope 3 {
-          debug v => _10;                  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-      }
-      scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-          debug r => _4;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-          StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-          _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-          _3 = move _4;                    // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-          StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-          _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-          switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-      }
-  
-      bb1: {
-          StorageLive(_10);                // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-          _10 = ((_3 as Ok).0: u32);       // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-          _2 = _10;                        // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-          StorageDead(_10);                // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-          StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-          StorageLive(_11);                // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-          _11 = _2;                        // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-          Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          ((_0 as Ok).0: u32) = move _11;  // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          StorageDead(_11);                // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      }
-  
-      bb3: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          _6 = ((_3 as Err).0: i32);       // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          StorageLive(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-          StorageLive(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          _9 = _6;                         // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          _8 = move _9;                    // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-          ((_0 as Err).0: i32) = move _8;  // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
-          Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          StorageDead(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-          StorageDead(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-          StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
deleted file mode 100644
index eb5af2227ec..00000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
+++ /dev/null
@@ -1,83 +0,0 @@
-// MIR for `try_identity` after SimplifyBranchSame
-
-fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-    debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-    let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-    let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-    let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-    let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-    let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-    let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
-    let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-    let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-    let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-    let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
-    scope 1 {
-        debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-    }
-    scope 2 {
-        debug e => _6;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-        scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-            debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        }
-        scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-            debug e => _8;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-        }
-    }
-    scope 3 {
-        debug v => _10;                  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-    }
-    scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-        debug r => _4;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-    }
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-        StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-        StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-        _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-        _3 = move _4;                    // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-        StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-        _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-        switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-    }
-
-    bb1: {
-        StorageLive(_10);                // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-        _10 = ((_3 as Ok).0: u32);       // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-        _2 = _10;                        // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-        StorageDead(_10);                // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-        StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-        StorageLive(_11);                // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-        _11 = _2;                        // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-        Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        ((_0 as Ok).0: u32) = move _11;  // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        StorageDead(_11);                // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-        StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-
-    bb2: {
-        unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    }
-
-    bb3: {
-        StorageLive(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-        _6 = ((_3 as Err).0: i32);       // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-        StorageLive(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-        StorageLive(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-        _9 = _6;                         // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-        _8 = move _9;                    // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        StorageDead(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-        ((_0 as Err).0: i32) = move _8;  // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
-        Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        StorageDead(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-        StorageDead(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-        StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-        StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-}
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
deleted file mode 100644
index 1efa8a67e5c..00000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
+++ /dev/null
@@ -1,58 +0,0 @@
-// MIR for `try_identity` after SimplifyLocals
-
-fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-    debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-    let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-    let mut _2: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    let mut _3: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-    let _4: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-    let mut _5: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-    let mut _6: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-    scope 1 {
-        debug y => ((_0 as Ok).0: u32);  // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-    }
-    scope 2 {
-        debug e => _4;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-        scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-            debug t => _6;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        }
-        scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-            debug e => _5;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-        }
-    }
-    scope 3 {
-        debug v => ((_0 as Ok).0: u32);  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-    }
-    scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-        debug r => _2;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-    }
-
-    bb0: {
-        _2 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-        _3 = discriminant(_2);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-        switchInt(move _3) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-    }
-
-    bb1: {
-        ((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-        Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-
-    bb2: {
-        unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    }
-
-    bb3: {
-        StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-        StorageLive(_5);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-        StorageLive(_6);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-        StorageDead(_6);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-        Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        StorageDead(_5);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-        StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-}
diff --git a/src/test/run-make/valid-print-requests/Makefile b/src/test/run-make/valid-print-requests/Makefile
new file mode 100644
index 00000000000..c325e536e7c
--- /dev/null
+++ b/src/test/run-make/valid-print-requests/Makefile
@@ -0,0 +1,4 @@
+include ../../run-make-fulldeps/tools.mk
+
+all:
+	$(RUSTC) --print uwu 2>&1 | diff - valid-print-requests.stderr
diff --git a/src/test/run-make/valid-print-requests/valid-print-requests.stderr b/src/test/run-make/valid-print-requests/valid-print-requests.stderr
new file mode 100644
index 00000000000..85782866d12
--- /dev/null
+++ b/src/test/run-make/valid-print-requests/valid-print-requests.stderr
@@ -0,0 +1,2 @@
+error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args`
+
diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml
index 18a1a3fadea..7ef7ec90cd2 100644
--- a/src/test/rustdoc-gui/sidebar-links-color.goml
+++ b/src/test/rustdoc-gui/sidebar-links-color.goml
@@ -4,230 +4,168 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
 // This is needed so that the text color is computed.
 show-text: true
 
-// Ayu theme
-local-storage: {
-    "rustdoc-theme": "ayu",
-    "rustdoc-use-system-theme": "false",
-}
-reload:
-
-// Struct
-assert-css: (
-    ".sidebar .block.struct a:not(.current)",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.struct a:not(.current)"
-assert-css: (
-    ".sidebar .block.struct a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Enum
-assert-css: (
-    ".sidebar .block.enum a",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.enum a"
-assert-css: (
-    ".sidebar .block.enum a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Union
-assert-css: (
-    ".sidebar .block.union a",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.union a"
-assert-css: (
-    ".sidebar .block.union a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Trait
-assert-css: (
-    ".sidebar .block.trait a",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.trait a"
-assert-css: (
-    ".sidebar .block.trait a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Function
-assert-css: (
-    ".sidebar .block.fn a",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.fn a"
-assert-css: (
-    ".sidebar .block.fn a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Type definition
-assert-css: (
-    ".sidebar .block.type a",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.type a"
-assert-css: (
-    ".sidebar .block.type a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Keyword
-assert-css: (
-    ".sidebar .block.keyword a",
-    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.keyword a"
-assert-css: (
-    ".sidebar .block.keyword a:hover",
-    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-
-// Dark theme
-local-storage: {"rustdoc-theme": "dark"}
-reload:
-
-// Struct
-assert-css: (
-    ".sidebar .block.struct a:not(.current)",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.struct a:not(.current)"
-assert-css: (
-    ".sidebar .block.struct a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Enum
-assert-css: (
-    ".sidebar .block.enum a",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.enum a"
-assert-css: (
-    ".sidebar .block.enum a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Union
-assert-css: (
-    ".sidebar .block.union a",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.union a"
-assert-css: (
-    ".sidebar .block.union a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+define-function: (
+    "check-colors",
+    (
+        theme, struct, struct_hover, struct_hover_background, enum, enum_hover,
+        enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover,
+        trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover,
+        type_hover_background, keyword, keyword_hover, keyword_hover_background,
+    ),
+    [
+        ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }),
+        ("reload"),
+        // Struct
+        ("assert-css", (
+            ".sidebar .block.struct a:not(.current)",
+            {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.struct a:not(.current)"),
+        ("assert-css", (
+            ".sidebar .block.struct a:hover",
+            {"color": |struct_hover|, "background-color": |struct_hover_background|},
+        )),
+        // Enum
+        ("assert-css", (
+            ".sidebar .block.enum a",
+            {"color": |enum|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.enum a"),
+        ("assert-css", (
+            ".sidebar .block.enum a:hover",
+            {"color": |enum_hover|, "background-color": |enum_hover_background|},
+        )),
+        // Union
+        ("assert-css", (
+            ".sidebar .block.union a",
+            {"color": |union|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.union a"),
+        ("assert-css", (
+            ".sidebar .block.union a:hover",
+            {"color": |union_hover|, "background-color": |union_hover_background|},
+        )),
+        // Trait
+        ("assert-css", (
+            ".sidebar .block.trait a",
+            {"color": |trait|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.trait a"),
+        ("assert-css", (
+            ".sidebar .block.trait a:hover",
+            {"color": |trait_hover|, "background-color": |trait_hover_background|},
+        )),
+        // Function
+        ("assert-css", (
+            ".sidebar .block.fn a",
+            {"color": |fn|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.fn a"),
+        ("assert-css", (
+            ".sidebar .block.fn a:hover",
+            {"color": |fn_hover|, "background-color": |fn_hover_background|},
+        )),
+        // Type definition
+        ("assert-css", (
+            ".sidebar .block.type a",
+            {"color": |type|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.type a"),
+        ("assert-css", (
+            ".sidebar .block.type a:hover",
+            {"color": |type_hover|, "background-color": |type_hover_background|},
+        )),
+        // Keyword
+        ("assert-css", (
+            ".sidebar .block.keyword a",
+            {"color": |keyword|, "background-color": "rgba(0, 0, 0, 0)"},
+        )),
+        ("move-cursor-to", ".sidebar .block.keyword a"),
+        ("assert-css", (
+            ".sidebar .block.keyword a:hover",
+            {"color": |keyword_hover|, "background-color": |keyword_hover_background|},
+        )),
+    ]
 )
-// Trait
-assert-css: (
-    ".sidebar .block.trait a",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.trait a"
-assert-css: (
-    ".sidebar .block.trait a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Function
-assert-css: (
-    ".sidebar .block.fn a",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.fn a"
-assert-css: (
-    ".sidebar .block.fn a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Type definition
-assert-css: (
-    ".sidebar .block.type a",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.type a"
-assert-css: (
-    ".sidebar .block.type a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Keyword
-assert-css: (
-    ".sidebar .block.keyword a",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.keyword a"
-assert-css: (
-    ".sidebar .block.keyword a:hover",
-    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-
-// Light theme
-local-storage: {"rustdoc-theme": "light"}
-reload:
 
-// Struct
-assert-css: (
-    ".sidebar .block.struct a:not(.current)",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.struct a:not(.current)"
-assert-css: (
-    ".sidebar .block.struct a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Enum
-assert-css: (
-    ".sidebar .block.enum a",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.enum a"
-assert-css: (
-    ".sidebar .block.enum a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Union
-assert-css: (
-    ".sidebar .block.union a",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.union a"
-assert-css: (
-    ".sidebar .block.union a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Trait
-assert-css: (
-    ".sidebar .block.trait a",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.trait a"
-assert-css: (
-    ".sidebar .block.trait a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Function
-assert-css: (
-    ".sidebar .block.fn a",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.fn a"
-assert-css: (
-    ".sidebar .block.fn a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Type definition
-assert-css: (
-    ".sidebar .block.type a",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.type a"
-assert-css: (
-    ".sidebar .block.type a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Keyword
-assert-css: (
-    ".sidebar .block.keyword a",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.keyword a"
-assert-css: (
-    ".sidebar .block.keyword a:hover",
-    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+call-function: (
+    "check-colors",
+    {
+        "theme": "ayu",
+        "struct": "rgb(83, 177, 219)",
+        "struct_hover": "rgb(255, 180, 76)",
+        "struct_hover_background": "rgba(0, 0, 0, 0)",
+        "enum": "rgb(83, 177, 219)",
+        "enum_hover": "rgb(255, 180, 76)",
+        "enum_hover_background": "rgba(0, 0, 0, 0)",
+        "union": "rgb(83, 177, 219)",
+        "union_hover": "rgb(255, 180, 76)",
+        "union_hover_background": "rgba(0, 0, 0, 0)",
+        "trait": "rgb(83, 177, 219)",
+        "trait_hover": "rgb(255, 180, 76)",
+        "trait_hover_background": "rgba(0, 0, 0, 0)",
+        "fn": "rgb(83, 177, 219)",
+        "fn_hover": "rgb(255, 180, 76)",
+        "fn_hover_background": "rgba(0, 0, 0, 0)",
+        "type": "rgb(83, 177, 219)",
+        "type_hover": "rgb(255, 180, 76)",
+        "type_hover_background": "rgba(0, 0, 0, 0)",
+        "keyword": "rgb(83, 177, 219)",
+        "keyword_hover": "rgb(255, 180, 76)",
+        "keyword_hover_background": "rgba(0, 0, 0, 0)",
+    }
+)
+call-function: (
+    "check-colors",
+    {
+        "theme": "dark",
+        "struct": "rgb(253, 191, 53)",
+        "struct_hover": "rgb(253, 191, 53)",
+        "struct_hover_background": "rgb(68, 68, 68)",
+        "enum": "rgb(253, 191, 53)",
+        "enum_hover": "rgb(253, 191, 53)",
+        "enum_hover_background": "rgb(68, 68, 68)",
+        "union": "rgb(253, 191, 53)",
+        "union_hover": "rgb(253, 191, 53)",
+        "union_hover_background": "rgb(68, 68, 68)",
+        "trait": "rgb(253, 191, 53)",
+        "trait_hover": "rgb(253, 191, 53)",
+        "trait_hover_background": "rgb(68, 68, 68)",
+        "fn": "rgb(253, 191, 53)",
+        "fn_hover": "rgb(253, 191, 53)",
+        "fn_hover_background": "rgb(68, 68, 68)",
+        "type": "rgb(253, 191, 53)",
+        "type_hover": "rgb(253, 191, 53)",
+        "type_hover_background": "rgb(68, 68, 68)",
+        "keyword": "rgb(253, 191, 53)",
+        "keyword_hover": "rgb(253, 191, 53)",
+        "keyword_hover_background": "rgb(68, 68, 68)",
+    }
+)
+call-function: (
+    "check-colors",
+    {
+        "theme": "light",
+        "struct": "rgb(53, 109, 164)",
+        "struct_hover": "rgb(53, 109, 164)",
+        "struct_hover_background": "rgb(255, 255, 255)",
+        "enum": "rgb(53, 109, 164)",
+        "enum_hover": "rgb(53, 109, 164)",
+        "enum_hover_background": "rgb(255, 255, 255)",
+        "union": "rgb(53, 109, 164)",
+        "union_hover": "rgb(53, 109, 164)",
+        "union_hover_background": "rgb(255, 255, 255)",
+        "trait": "rgb(53, 109, 164)",
+        "trait_hover": "rgb(53, 109, 164)",
+        "trait_hover_background": "rgb(255, 255, 255)",
+        "fn": "rgb(53, 109, 164)",
+        "fn_hover": "rgb(53, 109, 164)",
+        "fn_hover_background": "rgb(255, 255, 255)",
+        "type": "rgb(53, 109, 164)",
+        "type_hover": "rgb(53, 109, 164)",
+        "type_hover_background": "rgb(255, 255, 255)",
+        "keyword": "rgb(53, 109, 164)",
+        "keyword_hover": "rgb(53, 109, 164)",
+        "keyword_hover_background": "rgb(255, 255, 255)",
+    }
 )
diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml
index c29571728a1..10508e86a36 100644
--- a/src/test/rustdoc-gui/theme-in-history.goml
+++ b/src/test/rustdoc-gui/theme-in-history.goml
@@ -3,7 +3,6 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // Set the theme to dark.
 local-storage: {
     "rustdoc-theme": "dark",
-    "rustdoc-preferred-dark-theme": "dark",
     "rustdoc-use-system-theme": "false",
 }
 // We reload the page so the local storage settings are being used.
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index ca77e483d6f..411eb3fba48 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -40,9 +40,9 @@ struct HelloWarn {}
 //~^ ERROR unsupported type attribute for diagnostic derive enum
 enum DiagnosticOnEnum {
     Foo,
-//~^ ERROR diagnostic slug not specified
+    //~^ ERROR diagnostic slug not specified
     Bar,
-//~^ ERROR diagnostic slug not specified
+    //~^ ERROR diagnostic slug not specified
 }
 
 #[derive(Diagnostic)]
@@ -211,9 +211,10 @@ struct LabelOnNonSpan {
 #[diag(compiletest_example, code = "E0123")]
 struct Suggest {
     #[suggestion(suggestion, code = "This is the suggested code")]
-    #[suggestion_short(suggestion, code = "This is the suggested code")]
-    #[suggestion_hidden(suggestion, code = "This is the suggested code")]
-    #[suggestion_verbose(suggestion, code = "This is the suggested code")]
+    #[suggestion(suggestion, code = "This is the suggested code", style = "normal")]
+    #[suggestion(suggestion, code = "This is the suggested code", style = "short")]
+    #[suggestion(suggestion, code = "This is the suggested code", style = "hidden")]
+    #[suggestion(suggestion, code = "This is the suggested code", style = "verbose")]
     suggestion: (Span, Applicability),
 }
 
@@ -536,8 +537,7 @@ struct LabelWithTrailingList {
 
 #[derive(LintDiagnostic)]
 #[diag(compiletest_example)]
-struct LintsGood {
-}
+struct LintsGood {}
 
 #[derive(LintDiagnostic)]
 #[diag(compiletest_example)]
@@ -683,7 +683,7 @@ struct RawIdentDiagnosticArg {
 #[diag(compiletest_example)]
 struct SubdiagnosticBad {
     #[subdiagnostic(bad)]
-//~^ ERROR `#[subdiagnostic(bad)]` is not a valid attribute
+    //~^ ERROR `#[subdiagnostic(bad)]` is not a valid attribute
     note: Note,
 }
 
@@ -691,7 +691,7 @@ struct SubdiagnosticBad {
 #[diag(compiletest_example)]
 struct SubdiagnosticBadStr {
     #[subdiagnostic = "bad"]
-//~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute
+    //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute
     note: Note,
 }
 
@@ -699,7 +699,7 @@ struct SubdiagnosticBadStr {
 #[diag(compiletest_example)]
 struct SubdiagnosticBadTwice {
     #[subdiagnostic(bad, bad)]
-//~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+    //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
     note: Note,
 }
 
@@ -707,7 +707,7 @@ struct SubdiagnosticBadTwice {
 #[diag(compiletest_example)]
 struct SubdiagnosticBadLitStr {
     #[subdiagnostic("bad")]
-//~^ ERROR `#[subdiagnostic("...")]` is not a valid attribute
+    //~^ ERROR `#[subdiagnostic("...")]` is not a valid attribute
     note: Note,
 }
 
@@ -715,7 +715,7 @@ struct SubdiagnosticBadLitStr {
 #[diag(compiletest_example)]
 struct SubdiagnosticEagerLint {
     #[subdiagnostic(eager)]
-//~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+    //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
     note: Note,
 }
 
@@ -731,11 +731,7 @@ struct SubdiagnosticEagerCorrect {
 // after the `span_suggestion` call - which breaks eager translation.
 
 #[derive(Subdiagnostic)]
-#[suggestion_short(
-    use_instead,
-    applicability = "machine-applicable",
-    code = "{correct}"
-)]
+#[suggestion(use_instead, applicability = "machine-applicable", code = "{correct}")]
 pub(crate) struct SubdiagnosticWithSuggestion {
     #[primary_span]
     span: Span,
@@ -796,3 +792,10 @@ struct SuggestionsInvalidLiteral {
     //~^ ERROR `code = "..."`/`code(...)` must contain only string literals
     sub: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionStyleGood {
+    #[suggestion(code = "", style = "hidden")]
+    sub: Span,
+}
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 859c272b6ba..b4c211db47c 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -261,41 +261,41 @@ LL |     #[label(label)]
    |     ^^^^^^^^^^^^^^^
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:223:5
+  --> $DIR/diagnostic-derive.rs:224:5
    |
 LL |     #[suggestion(suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:231:18
+  --> $DIR/diagnostic-derive.rs:232:18
    |
 LL |     #[suggestion(nonsense = "bar")]
    |                  ^^^^^^^^^^^^^^^^
    |
-   = help: only `code` and `applicability` are valid nested attributes
+   = help: only `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:231:5
+  --> $DIR/diagnostic-derive.rs:232:5
    |
 LL |     #[suggestion(nonsense = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion(msg = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:240:18
+  --> $DIR/diagnostic-derive.rs:241:18
    |
 LL |     #[suggestion(msg = "bar")]
    |                  ^^^^^^^^^^^
    |
-   = help: only `code` and `applicability` are valid nested attributes
+   = help: only `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:240:5
+  --> $DIR/diagnostic-derive.rs:241:5
    |
 LL |     #[suggestion(msg = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: wrong field type for suggestion
-  --> $DIR/diagnostic-derive.rs:263:5
+  --> $DIR/diagnostic-derive.rs:264:5
    |
 LL | /     #[suggestion(suggestion, code = "This is suggested code")]
 LL | |
@@ -305,55 +305,55 @@ LL | |     suggestion: Applicability,
    = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:279:24
+  --> $DIR/diagnostic-derive.rs:280:24
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                        ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:279:18
+  --> $DIR/diagnostic-derive.rs:280:18
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                  ^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:287:33
+  --> $DIR/diagnostic-derive.rs:288:33
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                                 ^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:287:18
+  --> $DIR/diagnostic-derive.rs:288:18
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                  ^^^^^^^^^^^^^
 
 error: `#[label = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:294:5
+  --> $DIR/diagnostic-derive.rs:295:5
    |
 LL |     #[label = "bar"]
    |     ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:445:44
+  --> $DIR/diagnostic-derive.rs:446:44
    |
 LL |     #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
    |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:447:24
+  --> $DIR/diagnostic-derive.rs:448:24
    |
 LL |     suggestion: (Span, Applicability),
    |                        ^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/diagnostic-derive.rs:453:44
+  --> $DIR/diagnostic-derive.rs:454:44
    |
 LL |     #[suggestion(suggestion, code = "...", applicability = "batman")]
    |                                            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label(foo)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:516:20
+  --> $DIR/diagnostic-derive.rs:517:20
    |
 LL |     #[label(label, foo)]
    |                    ^^^
@@ -361,13 +361,13 @@ LL |     #[label(label, foo)]
    = help: a diagnostic slug must be the first argument to the attribute
 
 error: `#[label(foo = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:524:20
+  --> $DIR/diagnostic-derive.rs:525:20
    |
 LL |     #[label(label, foo = "...")]
    |                    ^^^^^^^^^^^
 
 error: `#[label(foo(...))]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:532:20
+  --> $DIR/diagnostic-derive.rs:533:20
    |
 LL |     #[label(label, foo("..."))]
    |                    ^^^^^^^^^^
@@ -574,19 +574,19 @@ LL |     #[subdiagnostic(eager)]
    = help: eager subdiagnostics are not supported on lints
 
 error: expected at least one string literal for `code(...)`
-  --> $DIR/diagnostic-derive.rs:779:18
+  --> $DIR/diagnostic-derive.rs:775:18
    |
 LL |     #[suggestion(code())]
    |                  ^^^^^^
 
 error: `code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:787:23
+  --> $DIR/diagnostic-derive.rs:783:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^
 
 error: `code = "..."`/`code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:795:18
+  --> $DIR/diagnostic-derive.rs:791:18
    |
 LL |     #[suggestion(code = 3)]
    |                  ^^^^^^^^
@@ -652,7 +652,7 @@ LL | #[diag(nonsense, code = "E0123")]
    |        ^^^^^^^^ not found in `rustc_errors::fluent`
 
 error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-  --> $DIR/diagnostic-derive.rs:338:10
+  --> $DIR/diagnostic-derive.rs:339:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
index efec85eb52c..078ec3baac9 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
@@ -11,13 +11,13 @@
 #![crate_type = "lib"]
 
 extern crate rustc_errors;
+extern crate rustc_macros;
 extern crate rustc_session;
 extern crate rustc_span;
-extern crate rustc_macros;
 
 use rustc_errors::Applicability;
-use rustc_span::Span;
 use rustc_macros::Subdiagnostic;
+use rustc_span::Span;
 
 #[derive(Subdiagnostic)]
 #[label(parser_add_paren)]
@@ -40,7 +40,7 @@ enum B {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -165,7 +165,7 @@ enum P {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -177,7 +177,7 @@ enum Q {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -189,7 +189,7 @@ enum R {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -201,7 +201,7 @@ enum S {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -213,7 +213,7 @@ enum T {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -225,7 +225,7 @@ enum U {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -240,7 +240,7 @@ enum V {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -301,14 +301,14 @@ struct AB {
     #[primary_span]
     span: Span,
     #[skip_arg]
-    z: Z
+    z: Z,
 }
 
 #[derive(Subdiagnostic)]
 union AC {
-//~^ ERROR unexpected unsupported untagged union
+    //~^ ERROR unexpected unsupported untagged union
     span: u32,
-    b: u64
+    b: u64,
 }
 
 #[derive(Subdiagnostic)]
@@ -372,7 +372,7 @@ enum AI {
         #[applicability]
         applicability: Applicability,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -427,7 +427,7 @@ struct AN {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="...", applicability = "foo")]
+#[suggestion(parser_add_paren, code = "...", applicability = "foo")]
 //~^ ERROR invalid applicability
 struct AO {
     #[primary_span]
@@ -437,7 +437,7 @@ struct AO {
 #[derive(Subdiagnostic)]
 #[help(parser_add_paren)]
 struct AP {
-    var: String
+    var: String,
 }
 
 #[derive(Subdiagnostic)]
@@ -452,7 +452,7 @@ struct AR {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="...", applicability = "machine-applicable")]
+#[suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")]
 struct AS {
     #[primary_span]
     span: Span,
@@ -467,11 +467,11 @@ enum AT {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+#[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")]
 struct AU {
     #[primary_span]
     span: Span,
@@ -479,7 +479,7 @@ struct AU {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+#[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")]
 //~^ ERROR `var` doesn't refer to a field on this type
 struct AV {
     #[primary_span]
@@ -488,22 +488,22 @@ struct AV {
 
 #[derive(Subdiagnostic)]
 enum AW {
-    #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+    #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")]
     A {
         #[primary_span]
         span: Span,
         var: String,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
 enum AX {
-    #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
-//~^ ERROR `var` doesn't refer to a field on this type
+    #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")]
+    //~^ ERROR `var` doesn't refer to a field on this type
     A {
         #[primary_span]
         span: Span,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -659,7 +659,7 @@ enum BL {
         /// ..and the field
         #[primary_span]
         span: Span,
-    }
+    },
 }
 
 #[derive(Subdiagnostic)]
@@ -706,3 +706,95 @@ struct BQ {
     span: Span,
     r#type: String,
 }
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "")]
+struct SuggestionStyleDefault {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = "short")]
+struct SuggestionStyleShort {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = "hidden")]
+struct SuggestionStyleHidden {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = "verbose")]
+struct SuggestionStyleVerbose {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = "tool-only")]
+struct SuggestionStyleToolOnly {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")]
+//~^ ERROR specified multiple times
+//~| NOTE previously specified here
+struct SuggestionStyleTwice {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion_hidden(parser_add_paren, code = "")]
+//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
+struct SuggestionStyleOldSyntax {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion_hidden(parser_add_paren, code = "", style = "normal")]
+//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
+struct SuggestionStyleOldAndNewSyntax {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = "foo")]
+//~^ ERROR invalid suggestion style
+struct SuggestionStyleInvalid1 {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style = 42)]
+//~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute
+struct SuggestionStyleInvalid2 {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style)]
+//~^ ERROR `#[suggestion(style)]` is not a valid attribute
+struct SuggestionStyleInvalid3 {
+    #[primary_span]
+    sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parser_add_paren, code = "", style("foo"))]
+//~^ ERROR `#[suggestion(style(...))]` is not a valid attribute
+struct SuggestionStyleInvalid4 {
+    #[primary_span]
+    sub: Span,
+}
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
index a85a8711eac..8e06c43e6d0 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
@@ -186,7 +186,7 @@ error: unexpected unsupported untagged union
 LL | / union AC {
 LL | |
 LL | |     span: u32,
-LL | |     b: u64
+LL | |     b: u64,
 LL | | }
    | |_^
 
@@ -253,10 +253,10 @@ LL | #[suggestion(parser_add_paren)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/subdiagnostic-derive.rs:430:45
+  --> $DIR/subdiagnostic-derive.rs:430:46
    |
-LL | #[suggestion(parser_add_paren, code ="...", applicability = "foo")]
-   |                                             ^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(parser_add_paren, code = "...", applicability = "foo")]
+   |                                              ^^^^^^^^^^^^^^^^^^^^^
 
 error: suggestion without `#[primary_span]` field
   --> $DIR/subdiagnostic-derive.rs:448:1
@@ -275,16 +275,16 @@ LL | #[label]
    | ^^^^^^^^
 
 error: `var` doesn't refer to a field on this type
-  --> $DIR/subdiagnostic-derive.rs:482:38
+  --> $DIR/subdiagnostic-derive.rs:482:39
    |
-LL | #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
-   |                                      ^^^^^^^
+LL | #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")]
+   |                                       ^^^^^^^
 
 error: `var` doesn't refer to a field on this type
-  --> $DIR/subdiagnostic-derive.rs:501:42
+  --> $DIR/subdiagnostic-derive.rs:501:43
    |
-LL |     #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
-   |                                          ^^^^^^^
+LL |     #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")]
+   |                                           ^^^^^^^
 
 error: `#[suggestion_part]` is not a valid attribute
   --> $DIR/subdiagnostic-derive.rs:524:5
@@ -320,7 +320,7 @@ error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
 LL | #[multipart_suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")]
    |                                          ^^^^^^^^^^^^
    |
-   = help: only `applicability` is a valid nested attributes
+   = help: only `style` and `applicability` are valid nested attributes
 
 error: multipart suggestion without any `#[suggestion_part(...)]` fields
   --> $DIR/subdiagnostic-derive.rs:536:1
@@ -445,6 +445,62 @@ error: `code = "..."`/`code(...)` must contain only string literals
 LL |     #[suggestion_part(code = 3)]
    |                       ^^^^^^^^
 
+error: specified multiple times
+  --> $DIR/subdiagnostic-derive.rs:746:61
+   |
+LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")]
+   |                                                             ^^^^^^^^^^^^^^^^
+   |
+note: previously specified here
+  --> $DIR/subdiagnostic-derive.rs:746:43
+   |
+LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")]
+   |                                           ^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_hidden(...)]` is not a valid attribute
+  --> $DIR/subdiagnostic-derive.rs:755:1
+   |
+LL | #[suggestion_hidden(parser_add_paren, code = "")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: Use `#[suggestion(..., style = "hidden")]` instead
+
+error: `#[suggestion_hidden(...)]` is not a valid attribute
+  --> $DIR/subdiagnostic-derive.rs:763:1
+   |
+LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: Use `#[suggestion(..., style = "hidden")]` instead
+
+error: invalid suggestion style
+  --> $DIR/subdiagnostic-derive.rs:771:51
+   |
+LL | #[suggestion(parser_add_paren, code = "", style = "foo")]
+   |                                                   ^^^^^
+   |
+   = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only`
+
+error: `#[suggestion(style = ...)]` is not a valid attribute
+  --> $DIR/subdiagnostic-derive.rs:779:43
+   |
+LL | #[suggestion(parser_add_paren, code = "", style = 42)]
+   |                                           ^^^^^^^^^^
+
+error: `#[suggestion(style)]` is not a valid attribute
+  --> $DIR/subdiagnostic-derive.rs:787:43
+   |
+LL | #[suggestion(parser_add_paren, code = "", style)]
+   |                                           ^^^^^
+   |
+   = help: a diagnostic slug must be the first argument to the attribute
+
+error: `#[suggestion(style(...))]` is not a valid attribute
+  --> $DIR/subdiagnostic-derive.rs:795:43
+   |
+LL | #[suggestion(parser_add_paren, code = "", style("foo"))]
+   |                                           ^^^^^^^^^^^^
+
 error: cannot find attribute `foo` in this scope
   --> $DIR/subdiagnostic-derive.rs:63:3
    |
@@ -505,6 +561,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
 LL | #[label(slug)]
    |         ^^^^ not found in `rustc_errors::fluent`
 
-error: aborting due to 72 previous errors
+error: aborting due to 79 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 41f97e4326a..1911f0f9c94 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -8,6 +8,7 @@ colored = "2"
 diff = "0.1.10"
 unified-diff = "0.2.1"
 getopts = "0.2"
+miropt-test-tools = { path = "../miropt-test-tools" }
 tracing = "0.1"
 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
 regex = "1.0"
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 0260f684838..9a432f11f82 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -2,11 +2,12 @@ pub use self::Mode::*;
 
 use std::ffi::OsString;
 use std::fmt;
+use std::iter;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::str::FromStr;
 
-use crate::util::PathBufExt;
+use crate::util::{add_dylib_path, PathBufExt};
 use lazycell::LazyCell;
 use test::ColorConfig;
 
@@ -385,8 +386,7 @@ impl Config {
     }
 
     fn target_cfg(&self) -> &TargetCfg {
-        self.target_cfg
-            .borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target, &self.target_rustcflags))
+        self.target_cfg.borrow_with(|| TargetCfg::new(self))
     }
 
     pub fn matches_arch(&self, arch: &str) -> bool {
@@ -457,21 +457,23 @@ pub enum Endian {
 }
 
 impl TargetCfg {
-    fn new(rustc_path: &Path, target: &str, target_rustcflags: &Vec<String>) -> TargetCfg {
-        let output = match Command::new(rustc_path)
+    fn new(config: &Config) -> TargetCfg {
+        let mut command = Command::new(&config.rustc_path);
+        add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
+        let output = match command
             .arg("--print=cfg")
             .arg("--target")
-            .arg(target)
-            .args(target_rustcflags)
+            .arg(&config.target)
+            .args(&config.target_rustcflags)
             .output()
         {
             Ok(output) => output,
-            Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path),
+            Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", config.rustc_path),
         };
         if !output.status.success() {
             panic!(
                 "error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}",
-                rustc_path,
+                config.rustc_path,
                 String::from_utf8(output.stdout).unwrap(),
                 String::from_utf8(output.stderr).unwrap(),
             );
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8af5f1da694..dee14405287 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -13,7 +13,7 @@ use crate::errors::{self, Error, ErrorKind};
 use crate::header::TestProps;
 use crate::json;
 use crate::read2::read2_abbreviated;
-use crate::util::{logv, PathBufExt};
+use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
 use crate::ColorConfig;
 use regex::{Captures, Regex};
 use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@@ -26,6 +26,7 @@ use std::fs::{self, create_dir_all, File, OpenOptions};
 use std::hash::{Hash, Hasher};
 use std::io::prelude::*;
 use std::io::{self, BufReader};
+use std::iter;
 use std::path::{Path, PathBuf};
 use std::process::{Child, Command, ExitStatus, Output, Stdio};
 use std::str;
@@ -72,19 +73,6 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
     f()
 }
 
-/// The name of the environment variable that holds dynamic library locations.
-pub fn dylib_env_var() -> &'static str {
-    if cfg!(windows) {
-        "PATH"
-    } else if cfg!(target_os = "macos") {
-        "DYLD_LIBRARY_PATH"
-    } else if cfg!(target_os = "haiku") {
-        "LIBRARY_PATH"
-    } else {
-        "LD_LIBRARY_PATH"
-    }
-}
-
 /// The platform-specific library name
 pub fn get_lib_name(lib: &str, dylib: bool) -> String {
     // In some casess (e.g. MUSL), we build a static
@@ -1811,16 +1799,7 @@ impl<'test> TestCx<'test> {
 
         // Need to be sure to put both the lib_path and the aux path in the dylib
         // search path for the child.
-        let mut path =
-            env::split_paths(&env::var_os(dylib_env_var()).unwrap_or_default()).collect::<Vec<_>>();
-        if let Some(p) = aux_path {
-            path.insert(0, PathBuf::from(p))
-        }
-        path.insert(0, PathBuf::from(lib_path));
-
-        // Add the new dylib search path var
-        let newpath = env::join_paths(&path).unwrap();
-        command.env(dylib_env_var(), newpath);
+        add_dylib_path(&mut command, iter::once(lib_path).chain(aux_path));
 
         let mut child = disable_error_reporting(|| command.spawn())
             .unwrap_or_else(|_| panic!("failed to exec `{:?}`", &command));
@@ -3399,103 +3378,49 @@ impl<'test> TestCx<'test> {
             }
         }
 
-        for l in test_file_contents.lines() {
-            if l.starts_with("// EMIT_MIR ") {
-                let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
-                let mut test_names = test_name.split(' ');
-                // sometimes we specify two files so that we get a diff between the two files
-                let test_name = test_names.next().unwrap();
-                let mut expected_file;
-                let from_file;
-                let to_file;
-
-                if test_name.ends_with(".diff") {
-                    let trimmed = test_name.trim_end_matches(".diff");
-                    let test_against = format!("{}.after.mir", trimmed);
-                    from_file = format!("{}.before.mir", trimmed);
-                    expected_file = format!("{}{}.diff", trimmed, bit_width);
-                    assert!(
-                        test_names.next().is_none(),
-                        "two mir pass names specified for MIR diff"
-                    );
-                    to_file = Some(test_against);
-                } else if let Some(first_pass) = test_names.next() {
-                    let second_pass = test_names.next().unwrap();
-                    assert!(
-                        test_names.next().is_none(),
-                        "three mir pass names specified for MIR diff"
-                    );
-                    expected_file =
-                        format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
-                    let second_file = format!("{}.{}.mir", test_name, second_pass);
-                    from_file = format!("{}.{}.mir", test_name, first_pass);
-                    to_file = Some(second_file);
-                } else {
-                    let ext_re = Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
-                    let cap = ext_re
-                        .captures_iter(test_name)
-                        .next()
-                        .expect("test_name has an invalid extension");
-                    let extension = cap.get(1).unwrap().as_str();
-                    expected_file = format!(
-                        "{}{}{}",
-                        test_name.trim_end_matches(extension),
-                        bit_width,
-                        extension,
-                    );
-                    from_file = test_name.to_string();
-                    assert!(
-                        test_names.next().is_none(),
-                        "two mir pass names specified for MIR dump"
+        let files = miropt_test_tools::files_for_miropt_test(
+            &self.testpaths.file,
+            self.config.get_pointer_width(),
+        );
+
+        for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files {
+            let dumped_string = if let Some(after) = to_file {
+                self.diff_mir_files(from_file.into(), after.into())
+            } else {
+                let mut output_file = PathBuf::new();
+                output_file.push(self.get_mir_dump_dir());
+                output_file.push(&from_file);
+                debug!(
+                    "comparing the contents of: {} with {}",
+                    output_file.display(),
+                    expected_file.display()
+                );
+                if !output_file.exists() {
+                    panic!(
+                        "Output file `{}` from test does not exist, available files are in `{}`",
+                        output_file.display(),
+                        output_file.parent().unwrap().display()
                     );
-                    to_file = None;
-                };
-                if !expected_file.starts_with(&test_crate) {
-                    expected_file = format!("{}.{}", test_crate, expected_file);
                 }
-                let expected_file = test_dir.join(expected_file);
+                self.check_mir_test_timestamp(&from_file, &output_file);
+                let dumped_string = fs::read_to_string(&output_file).unwrap();
+                self.normalize_output(&dumped_string, &[])
+            };
 
-                let dumped_string = if let Some(after) = to_file {
-                    self.diff_mir_files(from_file.into(), after.into())
-                } else {
-                    let mut output_file = PathBuf::new();
-                    output_file.push(self.get_mir_dump_dir());
-                    output_file.push(&from_file);
-                    debug!(
-                        "comparing the contents of: {} with {}",
-                        output_file.display(),
+            if self.config.bless {
+                let _ = std::fs::remove_file(&expected_file);
+                std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
+            } else {
+                if !expected_file.exists() {
+                    panic!("Output file `{}` from test does not exist", expected_file.display());
+                }
+                let expected_string = fs::read_to_string(&expected_file).unwrap();
+                if dumped_string != expected_string {
+                    print!("{}", write_diff(&expected_string, &dumped_string, 3));
+                    panic!(
+                        "Actual MIR output differs from expected MIR output {}",
                         expected_file.display()
                     );
-                    if !output_file.exists() {
-                        panic!(
-                            "Output file `{}` from test does not exist, available files are in `{}`",
-                            output_file.display(),
-                            output_file.parent().unwrap().display()
-                        );
-                    }
-                    self.check_mir_test_timestamp(&from_file, &output_file);
-                    let dumped_string = fs::read_to_string(&output_file).unwrap();
-                    self.normalize_output(&dumped_string, &[])
-                };
-
-                if self.config.bless {
-                    let _ = std::fs::remove_file(&expected_file);
-                    std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
-                } else {
-                    if !expected_file.exists() {
-                        panic!(
-                            "Output file `{}` from test does not exist",
-                            expected_file.display()
-                        );
-                    }
-                    let expected_string = fs::read_to_string(&expected_file).unwrap();
-                    if dumped_string != expected_string {
-                        print!("{}", write_diff(&expected_string, &dumped_string, 3));
-                        panic!(
-                            "Actual MIR output differs from expected MIR output {}",
-                            expected_file.display()
-                        );
-                    }
                 }
             }
         }
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index e5ff0906be8..ec36f1e4fb7 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -2,6 +2,7 @@ use crate::common::Config;
 use std::env;
 use std::ffi::OsStr;
 use std::path::PathBuf;
+use std::process::Command;
 
 use tracing::*;
 
@@ -111,3 +112,25 @@ impl PathBufExt for PathBuf {
         }
     }
 }
+
+/// The name of the environment variable that holds dynamic library locations.
+pub fn dylib_env_var() -> &'static str {
+    if cfg!(windows) {
+        "PATH"
+    } else if cfg!(target_os = "macos") {
+        "DYLD_LIBRARY_PATH"
+    } else if cfg!(target_os = "haiku") {
+        "LIBRARY_PATH"
+    } else {
+        "LD_LIBRARY_PATH"
+    }
+}
+
+/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
+/// If the dylib_path_var is already set for this cmd, the old value will be overwritten!
+pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator<Item = impl Into<PathBuf>>) {
+    let path_env = env::var_os(dylib_env_var());
+    let old_paths = path_env.as_ref().map(env::split_paths);
+    let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
+    cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
+}
diff --git a/src/tools/miropt-test-tools/Cargo.toml b/src/tools/miropt-test-tools/Cargo.toml
new file mode 100644
index 00000000000..8589a44cf1b
--- /dev/null
+++ b/src/tools/miropt-test-tools/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "miropt-test-tools"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+regex = "1.0"
diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs
new file mode 100644
index 00000000000..96819d3547b
--- /dev/null
+++ b/src/tools/miropt-test-tools/src/lib.rs
@@ -0,0 +1,70 @@
+use std::fs;
+
+pub struct MiroptTestFiles {
+    pub expected_file: std::path::PathBuf,
+    pub from_file: String,
+    pub to_file: Option<String>,
+}
+
+pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec<MiroptTestFiles> {
+    let mut out = Vec::new();
+    let test_file_contents = fs::read_to_string(&testfile).unwrap();
+
+    let test_dir = testfile.parent().unwrap();
+    let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace("-", "_");
+
+    let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
+        format!(".{}bit", bit_width)
+    } else {
+        String::new()
+    };
+
+    for l in test_file_contents.lines() {
+        if l.starts_with("// EMIT_MIR ") {
+            let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
+            let mut test_names = test_name.split(' ');
+            // sometimes we specify two files so that we get a diff between the two files
+            let test_name = test_names.next().unwrap();
+            let mut expected_file;
+            let from_file;
+            let to_file;
+
+            if test_name.ends_with(".diff") {
+                let trimmed = test_name.trim_end_matches(".diff");
+                let test_against = format!("{}.after.mir", trimmed);
+                from_file = format!("{}.before.mir", trimmed);
+                expected_file = format!("{}{}.diff", trimmed, bit_width);
+                assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff");
+                to_file = Some(test_against);
+            } else if let Some(first_pass) = test_names.next() {
+                let second_pass = test_names.next().unwrap();
+                assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff");
+                expected_file =
+                    format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
+                let second_file = format!("{}.{}.mir", test_name, second_pass);
+                from_file = format!("{}.{}.mir", test_name, first_pass);
+                to_file = Some(second_file);
+            } else {
+                let ext_re = regex::Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
+                let cap = ext_re
+                    .captures_iter(test_name)
+                    .next()
+                    .expect("test_name has an invalid extension");
+                let extension = cap.get(1).unwrap().as_str();
+                expected_file =
+                    format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,);
+                from_file = test_name.to_string();
+                assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump");
+                to_file = None;
+            };
+            if !expected_file.starts_with(&test_crate) {
+                expected_file = format!("{}.{}", test_crate, expected_file);
+            }
+            let expected_file = test_dir.join(expected_file);
+
+            out.push(MiroptTestFiles { expected_file, from_file, to_file });
+        }
+    }
+
+    out
+}
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 471d78a2922..774c97b7777 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -7,6 +7,7 @@ autobins = false
 [dependencies]
 cargo_metadata = "0.14"
 regex = "1"
+miropt-test-tools = { path = "../miropt-test-tools" }
 lazy_static = "1"
 walkdir = "2"
 
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index fc0bce58572..698e4850bea 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -47,6 +47,7 @@ pub mod error_codes_check;
 pub mod errors;
 pub mod extdeps;
 pub mod features;
+pub mod mir_opt_tests;
 pub mod pal;
 pub mod primitive_docs;
 pub mod style;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index ca785042aaa..ee883777c31 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -64,6 +64,7 @@ fn main() {
         // Checks over tests.
         check!(debug_artifacts, &src_path);
         check!(ui_tests, &src_path);
+        check!(mir_opt_tests, &src_path);
 
         // Checks that only make sense for the compiler.
         check!(errors, &compiler_path);
diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs
new file mode 100644
index 00000000000..f9e8b55497b
--- /dev/null
+++ b/src/tools/tidy/src/mir_opt_tests.rs
@@ -0,0 +1,37 @@
+//! Tidy check to ensure that mir opt directories do not have stale files.
+
+use std::collections::HashSet;
+use std::path::{Path, PathBuf};
+
+pub fn check(path: &Path, bad: &mut bool) {
+    let mut rs_files = Vec::<PathBuf>::new();
+    let mut output_files = HashSet::<PathBuf>::new();
+    let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter();
+
+    for file in files.filter_map(Result::ok).filter(|e| e.file_type().is_file()) {
+        let filepath = file.path();
+        if filepath.extension() == Some("rs".as_ref()) {
+            rs_files.push(filepath.to_owned());
+        } else {
+            output_files.insert(filepath.to_owned());
+        }
+    }
+
+    for file in rs_files {
+        for bw in [32, 64] {
+            for output_file in miropt_test_tools::files_for_miropt_test(&file, bw) {
+                output_files.remove(&output_file.expected_file);
+            }
+        }
+    }
+
+    for extra in output_files {
+        if extra.file_name() != Some("README.md".as_ref()) {
+            tidy_error!(
+                bad,
+                "the following output file is not associated with any mir-opt test, you can remove it: {}",
+                extra.display()
+            );
+        }
+    }
+}