about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs30
-rw-r--r--compiler/rustc_mir/src/transform/const_goto.rs2
-rw-r--r--compiler/rustc_mir/src/transform/const_prop.rs12
-rw-r--r--compiler/rustc_mir/src/transform/deduplicate_blocks.rs2
-rw-r--r--compiler/rustc_mir/src/transform/dest_prop.rs4
-rw-r--r--compiler/rustc_mir/src/transform/early_otherwise_branch.rs2
-rw-r--r--compiler/rustc_mir/src/transform/inline.rs2
-rw-r--r--compiler/rustc_mir/src/transform/match_branches.rs2
-rw-r--r--compiler/rustc_mir/src/transform/mod.rs2
-rw-r--r--compiler/rustc_mir/src/transform/multiple_return_terminators.rs2
-rw-r--r--compiler/rustc_mir/src/transform/nrvo.rs2
-rw-r--r--compiler/rustc_mir/src/transform/unreachable_prop.rs4
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs111
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs26
-rw-r--r--compiler/rustc_session/src/config.rs30
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_session/src/session.rs6
-rw-r--r--src/bootstrap/bin/rustc.rs18
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/clean/types.rs7
-rw-r--r--src/librustdoc/formats/item_type.rs2
-rw-r--r--src/librustdoc/formats/renderer.rs4
-rw-r--r--src/librustdoc/html/render/print_item.rs6
-rw-r--r--src/librustdoc/html/static/main.js6
-rw-r--r--src/librustdoc/json/conversions.rs65
-rw-r--r--src/librustdoc/json/mod.rs2
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs2
-rw-r--r--src/librustdoc/passes/doc_test_lints.rs2
-rw-r--r--src/librustdoc/passes/stripper.rs6
-rw-r--r--src/test/codegen/issue-59352.rs4
-rw-r--r--src/test/codegen/naked-noinline.rs2
-rw-r--r--src/test/codegen/sanitizer-no-sanitize-inlining.rs4
-rw-r--r--src/test/codegen/try_identity.rs2
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.rs2
-rw-r--r--src/test/mir-opt/const_prop/issue-66971.rs2
-rw-r--r--src/test/mir-opt/const_prop/issue-67019.rs2
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.rs2
-rw-r--r--src/test/mir-opt/early_otherwise_branch.rs2
-rw-r--r--src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs2
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.rs2
-rw-r--r--src/test/mir-opt/early_otherwise_branch_noopt.rs2
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place.rs2
-rw-r--r--src/test/mir-opt/inline/inline-trait-method_2.rs2
-rw-r--r--src/test/mir-opt/issues/issue-59352.rs2
-rw-r--r--src/test/mir-opt/multiple_return_terminators.rs2
-rw-r--r--src/test/mir-opt/simplify-arm-identity.rs2
-rw-r--r--src/test/mir-opt/simplify-arm.rs2
-rw-r--r--src/test/rustdoc-ui/doc-attr.rs7
-rw-r--r--src/test/rustdoc-ui/doc-attr.stderr11
-rw-r--r--src/test/rustdoc-ui/doc-attr2.rs11
-rw-r--r--src/test/rustdoc-ui/doc-attr2.stderr26
-rw-r--r--src/test/ui/attributes/doc-attr.rs7
-rw-r--r--src/test/ui/attributes/doc-attr.stderr11
-rw-r--r--src/test/ui/attributes/doc-attr2.rs11
-rw-r--r--src/test/ui/attributes/doc-attr2.stderr26
-rw-r--r--src/test/ui/const-generics/issues/issue-75299.rs2
-rw-r--r--src/test/ui/const_prop/inline_spans.rs2
-rw-r--r--src/test/ui/const_prop/inline_spans_lint_attribute.rs2
-rw-r--r--src/test/ui/consts/issue-66345.rs4
-rw-r--r--src/test/ui/consts/issue-67529.rs2
-rw-r--r--src/test/ui/consts/issue-67640.rs2
-rw-r--r--src/test/ui/consts/issue-67641.rs2
-rw-r--r--src/test/ui/consts/issue-67862.rs2
-rw-r--r--src/test/ui/consts/trait_specialization.rs2
-rw-r--r--src/test/ui/dest-prop/skeptic-miscompile.rs2
-rw-r--r--src/test/ui/issues/issue-50411.rs2
-rw-r--r--src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs2
-rw-r--r--src/test/ui/issues/issue-77002.rs2
-rw-r--r--src/test/ui/mir/auxiliary/issue_76375_aux.rs2
-rw-r--r--src/test/ui/mir/issue-66851.rs2
-rw-r--r--src/test/ui/mir/issue-67639-normalization-ice.rs2
-rw-r--r--src/test/ui/mir/issue-67710-inline-projection.rs2
-rw-r--r--src/test/ui/mir/issue-68841.rs2
-rw-r--r--src/test/ui/mir/issue-71793-inline-args-storage.rs2
-rw-r--r--src/test/ui/mir/issue-75053.rs2
-rw-r--r--src/test/ui/mir/issue-76248.rs2
-rw-r--r--src/test/ui/mir/issue-76375.rs2
-rw-r--r--src/test/ui/mir/issue-76740-copy-propagation.rs2
-rw-r--r--src/test/ui/mir/issue-77911.rs2
-rw-r--r--src/test/ui/mir/issue-78496.rs2
-rw-r--r--src/test/ui/mir/issue66339.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-45493.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-45885.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-68347.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-77306-1.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-77306-2.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/ice-issue-77564.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs4
-rw-r--r--src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr2
-rw-r--r--src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs2
-rw-r--r--src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs2
-rw-r--r--src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs2
-rw-r--r--src/test/ui/mir/ssa-analysis-regression-50041.rs2
-rw-r--r--src/test/ui/parser/match-arm-without-braces.rs87
-rw-r--r--src/test/ui/parser/match-arm-without-braces.stderr135
-rw-r--r--src/test/ui/polymorphization/promoted-function-3.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/const-caller-location.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/intrinsic-wrapper.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/pass.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/std-panic-locations.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs2
-rw-r--r--src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs2
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs2
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs2
-rw-r--r--src/test/ui/structs/issue-80853.rs (renamed from src/test/ui/structs/80853.rs)0
-rw-r--r--src/test/ui/structs/issue-80853.stderr (renamed from src/test/ui/structs/80853.stderr)2
-rw-r--r--src/tools/clippy/src/driver.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs2
113 files changed, 665 insertions, 188 deletions
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 9a11b534887..28646973620 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -566,7 +566,7 @@ fn test_debugging_options_tracking_hash() {
     tracked!(link_only, true);
     tracked!(merge_functions, Some(MergeFunctions::Disabled));
     tracked!(mir_emit_retag, true);
-    tracked!(mir_opt_level, 3);
+    tracked!(mir_opt_level, Some(4));
     tracked!(mutable_noalias, true);
     tracked!(new_llvm_pass_manager, true);
     tracked!(no_codegen, true);
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 12d849e3b94..e6f81ce828f 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3059,3 +3059,33 @@ declare_lint! {
     Allow,
     "No declared ABI for extern declaration"
 }
+
+declare_lint! {
+    /// The `invalid_doc_attributes` lint detects when the `#[doc(...)]` is
+    /// misused.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(warnings)]
+    ///
+    /// pub mod submodule {
+    ///     #![doc(test(no_crate_inject))]
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Previously, there were very like checks being performed on `#[doc(..)]`
+    /// unlike the other attributes. It'll now catch all the issues that it
+    /// silently ignored previously.
+    pub INVALID_DOC_ATTRIBUTES,
+    Warn,
+    "detects invalid `#[doc(...)]` attributes",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>",
+        edition: None,
+    };
+}
diff --git a/compiler/rustc_mir/src/transform/const_goto.rs b/compiler/rustc_mir/src/transform/const_goto.rs
index 3eb2e757644..b5c8b4bebc3 100644
--- a/compiler/rustc_mir/src/transform/const_goto.rs
+++ b/compiler/rustc_mir/src/transform/const_goto.rs
@@ -28,7 +28,7 @@ pub struct ConstGoto;
 
 impl<'tcx> MirPass<'tcx> for ConstGoto {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
+        if tcx.sess.mir_opt_level() < 4 {
             return;
         }
         trace!("Running ConstGoto on {:?}", body.source);
diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs
index 2a0e5e2c9c5..263df44f4d1 100644
--- a/compiler/rustc_mir/src/transform/const_prop.rs
+++ b/compiler/rustc_mir/src/transform/const_prop.rs
@@ -725,7 +725,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             return None;
         }
 
-        if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
+        if self.tcx.sess.mir_opt_level() >= 4 {
             self.eval_rvalue_with_identities(rvalue, place)
         } else {
             self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place))
@@ -903,7 +903,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
 
     /// Returns `true` if and only if this `op` should be const-propagated into.
     fn should_const_prop(&mut self, op: &OpTy<'tcx>) -> bool {
-        let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level;
+        let mir_opt_level = self.tcx.sess.mir_opt_level();
 
         if mir_opt_level == 0 {
             return false;
@@ -1071,9 +1071,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
         self.super_operand(operand, location);
 
-        // Only const prop copies and moves on `mir_opt_level=2` as doing so
+        // Only const prop copies and moves on `mir_opt_level=3` as doing so
         // currently slightly increases compile time in some cases.
-        if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
+        if self.tcx.sess.mir_opt_level() >= 3 {
             self.propagate_operand(operand)
         }
     }
@@ -1253,7 +1253,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
             TerminatorKind::SwitchInt { ref mut discr, .. } => {
                 // FIXME: This is currently redundant with `visit_operand`, but sadly
                 // always visiting operands currently causes a perf regression in LLVM codegen, so
-                // `visit_operand` currently only runs for propagates places for `mir_opt_level=3`.
+                // `visit_operand` currently only runs for propagates places for `mir_opt_level=4`.
                 self.propagate_operand(discr)
             }
             // None of these have Operands to const-propagate.
@@ -1272,7 +1272,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
             // Every argument in our function calls have already been propagated in `visit_operand`.
             //
             // NOTE: because LLVM codegen gives slight performance regressions with it, so this is
-            // gated on `mir_opt_level=2`.
+            // gated on `mir_opt_level=3`.
             TerminatorKind::Call { .. } => {}
         }
 
diff --git a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs
index 5f09159e91b..c4b51099f53 100644
--- a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs
+++ b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs
@@ -16,7 +16,7 @@ pub struct DeduplicateBlocks;
 
 impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
+        if tcx.sess.mir_opt_level() < 4 {
             return;
         }
         debug!("Running DeduplicateBlocks on `{:?}`", body.source);
diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs
index 46de5dba6e0..0822ab73c4c 100644
--- a/compiler/rustc_mir/src/transform/dest_prop.rs
+++ b/compiler/rustc_mir/src/transform/dest_prop.rs
@@ -127,9 +127,9 @@ pub struct DestinationPropagation;
 
 impl<'tcx> MirPass<'tcx> for DestinationPropagation {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        // Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove
+        // Only run at mir-opt-level=3 or higher for now (we don't fix up debuginfo and remove
         // storage statements at the moment).
-        if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
+        if tcx.sess.mir_opt_level() < 3 {
             return;
         }
 
diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
index b16a99d7f0d..821167fd9f0 100644
--- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
+++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
@@ -26,7 +26,7 @@ pub struct EarlyOtherwiseBranch;
 
 impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
+        if tcx.sess.mir_opt_level() < 3 {
             return;
         }
         trace!("running EarlyOtherwiseBranch on {:?}", body.source);
diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs
index 0a899273efe..cf85503b3d5 100644
--- a/compiler/rustc_mir/src/transform/inline.rs
+++ b/compiler/rustc_mir/src/transform/inline.rs
@@ -52,7 +52,7 @@ crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
         return enabled;
     }
 
-    tcx.sess.opts.debugging_opts.mir_opt_level >= 2
+    tcx.sess.mir_opt_level() >= 3
 }
 
 impl<'tcx> MirPass<'tcx> for Inline {
diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs
index 92b4ae397ae..e254f0553aa 100644
--- a/compiler/rustc_mir/src/transform/match_branches.rs
+++ b/compiler/rustc_mir/src/transform/match_branches.rs
@@ -40,7 +40,7 @@ pub struct MatchBranchSimplification;
 
 impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
+        if tcx.sess.mir_opt_level() < 3 {
             return;
         }
 
diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs
index 9cb8abf75c4..13546442f66 100644
--- a/compiler/rustc_mir/src/transform/mod.rs
+++ b/compiler/rustc_mir/src/transform/mod.rs
@@ -475,7 +475,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
 }
 
 fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-    let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;
+    let mir_opt_level = tcx.sess.mir_opt_level();
 
     // Lowering generator control-flow and variables has to happen before we do anything else
     // to them. We run some optimizations before that, because they may be harder to do on the state
diff --git a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs
index 617086622cc..4aaa0baa9f4 100644
--- a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs
+++ b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs
@@ -10,7 +10,7 @@ pub struct MultipleReturnTerminators;
 
 impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
+        if tcx.sess.mir_opt_level() < 4 {
             return;
         }
 
diff --git a/compiler/rustc_mir/src/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs
index ce02fb261df..445dc12909c 100644
--- a/compiler/rustc_mir/src/transform/nrvo.rs
+++ b/compiler/rustc_mir/src/transform/nrvo.rs
@@ -34,7 +34,7 @@ pub struct RenameReturnPlace;
 
 impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
+        if tcx.sess.mir_opt_level() == 0 {
             return;
         }
 
diff --git a/compiler/rustc_mir/src/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs
index e39c8656021..658c6b6e9db 100644
--- a/compiler/rustc_mir/src/transform/unreachable_prop.rs
+++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs
@@ -12,8 +12,8 @@ pub struct UnreachablePropagation;
 
 impl MirPass<'_> for UnreachablePropagation {
     fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
-            // Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt
+        if tcx.sess.mir_opt_level() < 4 {
+            // Enable only under -Zmir-opt-level=4 as in some cases (check the deeply-nested-opt
             // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code.
             return;
         }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 28bfaea4555..608b0248274 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1973,6 +1973,102 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
     }
 
+    /// Attempt to recover from match arm body with statements and no surrounding braces.
+    fn parse_arm_body_missing_braces(
+        &mut self,
+        first_expr: &P<Expr>,
+        arrow_span: Span,
+    ) -> Option<P<Expr>> {
+        if self.token.kind != token::Semi {
+            return None;
+        }
+        let start_snapshot = self.clone();
+        let semi_sp = self.token.span;
+        self.bump(); // `;`
+        let mut stmts =
+            vec![self.mk_stmt(first_expr.span, ast::StmtKind::Expr(first_expr.clone()))];
+        let err = |this: &mut Parser<'_>, stmts: Vec<ast::Stmt>| {
+            let span = stmts[0].span.to(stmts[stmts.len() - 1].span);
+            let mut err = this.struct_span_err(span, "`match` arm body without braces");
+            let (these, s, are) =
+                if stmts.len() > 1 { ("these", "s", "are") } else { ("this", "", "is") };
+            err.span_label(
+                span,
+                &format!(
+                    "{these} statement{s} {are} not surrounded by a body",
+                    these = these,
+                    s = s,
+                    are = are
+                ),
+            );
+            err.span_label(arrow_span, "while parsing the `match` arm starting here");
+            if stmts.len() > 1 {
+                err.multipart_suggestion(
+                    &format!("surround the statement{} with a body", s),
+                    vec![
+                        (span.shrink_to_lo(), "{ ".to_string()),
+                        (span.shrink_to_hi(), " }".to_string()),
+                    ],
+                    Applicability::MachineApplicable,
+                );
+            } else {
+                err.span_suggestion(
+                    semi_sp,
+                    "use a comma to end a `match` arm expression",
+                    ",".to_string(),
+                    Applicability::MachineApplicable,
+                );
+            }
+            err.emit();
+            this.mk_expr_err(span)
+        };
+        // We might have either a `,` -> `;` typo, or a block without braces. We need
+        // a more subtle parsing strategy.
+        loop {
+            if self.token.kind == token::CloseDelim(token::Brace) {
+                // We have reached the closing brace of the `match` expression.
+                return Some(err(self, stmts));
+            }
+            if self.token.kind == token::Comma {
+                *self = start_snapshot;
+                return None;
+            }
+            let pre_pat_snapshot = self.clone();
+            match self.parse_pat_no_top_alt(None) {
+                Ok(_pat) => {
+                    if self.token.kind == token::FatArrow {
+                        // Reached arm end.
+                        *self = pre_pat_snapshot;
+                        return Some(err(self, stmts));
+                    }
+                }
+                Err(mut err) => {
+                    err.cancel();
+                }
+            }
+
+            *self = pre_pat_snapshot;
+            match self.parse_stmt_without_recovery(true, ForceCollect::No) {
+                // Consume statements for as long as possible.
+                Ok(Some(stmt)) => {
+                    stmts.push(stmt);
+                }
+                Ok(None) => {
+                    *self = start_snapshot;
+                    break;
+                }
+                // We couldn't parse either yet another statement missing it's
+                // enclosing block nor the next arm's pattern or closing brace.
+                Err(mut stmt_err) => {
+                    stmt_err.cancel();
+                    *self = start_snapshot;
+                    break;
+                }
+            }
+        }
+        None
+    }
+
     pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
         let attrs = self.parse_outer_attributes()?;
         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
@@ -2007,6 +2103,21 @@ impl<'a> Parser<'a> {
 
             if require_comma {
                 let sm = this.sess.source_map();
+                if let Some(body) = this.parse_arm_body_missing_braces(&expr, arrow_span) {
+                    let span = body.span;
+                    return Ok((
+                        ast::Arm {
+                            attrs,
+                            pat,
+                            guard,
+                            body,
+                            span,
+                            id: DUMMY_NODE_ID,
+                            is_placeholder: false,
+                        },
+                        TrailingToken::None,
+                    ));
+                }
                 this.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]).map_err(
                     |mut err| {
                         match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 07746f2390d..a0f9616f72a 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -34,7 +34,7 @@ impl<'a> Parser<'a> {
 
     /// If `force_capture` is true, forces collection of tokens regardless of whether
     /// or not we have attributes
-    fn parse_stmt_without_recovery(
+    crate fn parse_stmt_without_recovery(
         &mut self,
         capture_semi: bool,
         force_collect: ForceCollect,
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 39245ea77e5..ed971951b0f 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -17,7 +17,9 @@ use rustc_hir::{
     self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID,
 };
 use rustc_hir::{MethodKind, Target};
-use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES};
+use rustc_session::lint::builtin::{
+    CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES,
+};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
@@ -544,6 +546,21 @@ impl CheckAttrVisitor<'tcx> {
                         {
                             return false;
                         }
+                    } else if meta.has_name(sym::test) {
+                        if CRATE_HIR_ID != hir_id {
+                            self.tcx.struct_span_lint_hir(
+                                INVALID_DOC_ATTRIBUTES,
+                                hir_id,
+                                meta.span(),
+                                |lint| {
+                                    lint.build(
+                                        "`#![doc(test(...)]` is only allowed as a crate level attribute"
+                                    )
+                                    .emit();
+                                },
+                            );
+                            return false;
+                        }
                     } else if let Some(i_meta) = meta.meta_item() {
                         if ![
                             sym::cfg,
@@ -568,7 +585,7 @@ impl CheckAttrVisitor<'tcx> {
                         .any(|m| i_meta.has_name(*m))
                         {
                             self.tcx.struct_span_lint_hir(
-                                UNUSED_ATTRIBUTES,
+                                INVALID_DOC_ATTRIBUTES,
                                 hir_id,
                                 i_meta.span,
                                 |lint| {
@@ -576,11 +593,6 @@ impl CheckAttrVisitor<'tcx> {
                                         "unknown `doc` attribute `{}`",
                                         i_meta.name_or_empty()
                                     ))
-                                    .warn(
-                                        "this was previously accepted by the compiler but is \
-                                        being phased out; it will become a hard error in \
-                                        a future release!",
-                                    )
                                     .emit();
                                 },
                             );
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 77a9a2b227c..f25828e2161 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1938,21 +1938,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             Some(SymbolManglingVersion::V0) => {}
         }
 
-        if debugging_opts.mir_opt_level > 1 {
-            // Functions inlined during MIR transform can, at best, make it impossible to
-            // effectively cover inlined functions, and, at worst, break coverage map generation
-            // during LLVM codegen. For example, function counter IDs are only unique within a
-            // function. Inlining after these counters are injected can produce duplicate counters,
-            // resulting in an invalid coverage map (and ICE); so this option combination is not
-            // allowed.
-            early_warn(
-                error_format,
-                &format!(
-                    "`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
+        if let Some(mir_opt_level) = debugging_opts.mir_opt_level {
+            if mir_opt_level > 1 {
+                // Functions inlined during MIR transform can, at best, make it impossible to
+                // effectively cover inlined functions, and, at worst, break coverage map generation
+                // during LLVM codegen. For example, function counter IDs are only unique within a
+                // function. Inlining after these counters are injected can produce duplicate counters,
+                // resulting in an invalid coverage map (and ICE); so this option combination is not
+                // allowed.
+                early_warn(
+                    error_format,
+                    &format!(
+                        "`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
                     is incompatible with `-Z instrument-coverage`. Inlining will be disabled.",
-                    debugging_opts.mir_opt_level,
-                ),
-            );
+                        mir_opt_level,
+                    ),
+                );
+            }
         }
     }
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 6e7d39547a1..79bbad8307b 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -999,8 +999,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     mir_emit_retag: bool = (false, parse_bool, [TRACKED],
         "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
         (default: no)"),
-    mir_opt_level: usize = (1, parse_uint, [TRACKED],
-        "MIR optimization level (0-3; default: 1)"),
+    mir_opt_level: Option<usize> = (None, parse_opt_uint, [TRACKED],
+        "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
     mutable_noalias: bool = (false, parse_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: no)"),
     new_llvm_pass_manager: bool = (false, parse_bool, [TRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 493bbb3a762..963df0fb4d7 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -640,6 +640,12 @@ impl Session {
     pub fn binary_dep_depinfo(&self) -> bool {
         self.opts.debugging_opts.binary_dep_depinfo
     }
+    pub fn mir_opt_level(&self) -> usize {
+        self.opts
+            .debugging_opts
+            .mir_opt_level
+            .unwrap_or_else(|| if self.opts.optimize != config::OptLevel::No { 2 } else { 1 })
+    }
 
     /// Gets the features enabled for the current compilation session.
     /// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 6b1be0ca09d..0ab5e9c63c9 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -138,21 +138,28 @@ fn main() {
         cmd.arg("-Z").arg("force-unstable-if-unmarked");
     }
 
+    let is_test = args.iter().any(|a| a == "--test");
     if verbose > 1 {
         let rust_env_vars =
             env::vars().filter(|(k, _)| k.starts_with("RUST") || k.starts_with("CARGO"));
+        let prefix = if is_test { "[RUSTC-SHIM] rustc --test" } else { "[RUSTC-SHIM] rustc" };
+        let prefix = match crate_name {
+            Some(crate_name) => format!("{} {}", prefix, crate_name),
+            None => prefix.to_string(),
+        };
         for (i, (k, v)) in rust_env_vars.enumerate() {
-            eprintln!("rustc env[{}]: {:?}={:?}", i, k, v);
+            eprintln!("{} env[{}]: {:?}={:?}", prefix, i, k, v);
         }
-        eprintln!("rustc working directory: {}", env::current_dir().unwrap().display());
+        eprintln!("{} working directory: {}", prefix, env::current_dir().unwrap().display());
         eprintln!(
-            "rustc command: {:?}={:?} {:?}",
+            "{} command: {:?}={:?} {:?}",
+            prefix,
             bootstrap::util::dylib_path_var(),
             env::join_paths(&dylib_path).unwrap(),
             cmd,
         );
-        eprintln!("sysroot: {:?}", sysroot);
-        eprintln!("libdir: {:?}", libdir);
+        eprintln!("{} sysroot: {:?}", prefix, sysroot);
+        eprintln!("{} libdir: {:?}", prefix, libdir);
     }
 
     let start = Instant::now();
@@ -166,7 +173,6 @@ fn main() {
     {
         if let Some(crate_name) = crate_name {
             let dur = start.elapsed();
-            let is_test = args.iter().any(|a| a == "--test");
             // If the user requested resource usage data, then
             // include that in addition to the timing output.
             let rusage_data =
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5d81498f8d2..29eb67f023f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2129,12 +2129,12 @@ fn clean_extern_crate(
     }
     // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
     vec![Item {
-        name: None,
+        name: Some(name),
         attrs: box krate.attrs.clean(cx),
         source: krate.span.clean(cx),
         def_id: crate_def_id,
         visibility: krate.vis.clean(cx),
-        kind: box ExternCrateItem(name, orig_name),
+        kind: box ExternCrateItem { src: orig_name },
     }]
 }
 
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index e3f47a85d51..e560843383e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -323,7 +323,10 @@ impl Item {
 
 #[derive(Clone, Debug)]
 crate enum ItemKind {
-    ExternCrateItem(Symbol, Option<Symbol>),
+    ExternCrateItem {
+        /// The crate's name, *not* the name it's imported as.
+        src: Option<Symbol>,
+    },
     ImportItem(Import),
     StructItem(Struct),
     UnionItem(Union),
@@ -376,7 +379,7 @@ impl ItemKind {
             TraitItem(t) => t.items.iter(),
             ImplItem(i) => i.items.iter(),
             ModuleItem(m) => m.items.iter(),
-            ExternCrateItem(_, _)
+            ExternCrateItem { .. }
             | ImportItem(_)
             | FunctionItem(_)
             | TypedefItem(_, _)
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index 7922a1ffa06..460d4b907c0 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -67,7 +67,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
 
         match *kind {
             clean::ModuleItem(..) => ItemType::Module,
-            clean::ExternCrateItem(..) => ItemType::ExternCrate,
+            clean::ExternCrateItem { .. } => ItemType::ExternCrate,
             clean::ImportItem(..) => ItemType::Import,
             clean::StructItem(..) => ItemType::Struct,
             clean::UnionItem(..) => ItemType::Union,
diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs
index b779363e5c7..0487da1e7d0 100644
--- a/src/librustdoc/formats/renderer.rs
+++ b/src/librustdoc/formats/renderer.rs
@@ -91,7 +91,9 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
             }
 
             cx.mod_item_out(&name)?;
-        } else if item.name.is_some() {
+        // FIXME: checking `item.name.is_some()` is very implicit and leads to lots of special
+        // cases. Use an explicit match instead.
+        } else if item.name.is_some() && !item.is_extern_crate() {
             prof.generic_activity_with_arg("render_item", &*item.name.unwrap_or(unknown).as_str())
                 .run(|| cx.item(item))?;
         }
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 6d61248f28e..6cdd3838023 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -240,7 +240,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
         }
 
         match *myitem.kind {
-            clean::ExternCrateItem(ref name, ref src) => {
+            clean::ExternCrateItem { ref src } => {
                 use crate::html::format::anchor;
 
                 match *src {
@@ -249,13 +249,13 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
                         "<tr><td><code>{}extern crate {} as {};",
                         myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()),
                         anchor(myitem.def_id, &*src.as_str(), cx.cache()),
-                        name
+                        myitem.name.as_ref().unwrap(),
                     ),
                     None => write!(
                         w,
                         "<tr><td><code>{}extern crate {};",
                         myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()),
-                        anchor(myitem.def_id, &*name.as_str(), cx.cache())
+                        anchor(myitem.def_id, &*myitem.name.as_ref().unwrap().as_str(), cx.cache()),
                     ),
                 }
                 w.write_str("</code></td></tr>");
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index c9b8100fd03..d5071cec0c8 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -1548,9 +1548,9 @@ function defocusSearchBar() {
                 } else if (type === "structfield" && parentType === "variant") {
                     // Structfields belonging to variants are special: the
                     // final path element is the enum name.
-                    var splitPath = item.path.split("::");
-                    var enumName = splitPath.pop();
-                    path = splitPath.join("::");
+                    var enumNameIdx = item.path.lastIndexOf("::");
+                    var enumName = item.path.substr(enumNameIdx + 2);
+                    path = item.path.substr(0, enumNameIdx);
                     displayPath = path + "::" + enumName + "::" + myparent.name + "::";
                     anchor = "#variant." + myparent.name + ".field." + name;
                     pageType = "enum";
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index da09d49a006..47e4f3f0aa3 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -10,6 +10,7 @@ use rustc_ast::ast;
 use rustc_hir::def::CtorKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
+use rustc_span::symbol::Symbol;
 use rustc_span::Pos;
 
 use rustdoc_json_types::*;
@@ -25,32 +26,33 @@ impl JsonRenderer<'_> {
         let item_type = ItemType::from(&item);
         let deprecation = item.deprecation(self.tcx);
         let clean::Item { source, name, attrs, kind, visibility, def_id } = item;
-        match *kind {
-            clean::StrippedItem(_) => None,
-            kind => Some(Item {
-                id: from_def_id(def_id),
-                crate_id: def_id.krate.as_u32(),
-                name: name.map(|sym| sym.to_string()),
-                source: self.convert_span(source),
-                visibility: self.convert_visibility(visibility),
-                docs: attrs.collapsed_doc_value(),
-                links: attrs
-                    .links
-                    .into_iter()
-                    .filter_map(|clean::ItemLink { link, did, .. }| {
-                        did.map(|did| (link, from_def_id(did)))
-                    })
-                    .collect(),
-                attrs: attrs
-                    .other_attrs
-                    .iter()
-                    .map(rustc_ast_pretty::pprust::attribute_to_string)
-                    .collect(),
-                deprecation: deprecation.map(from_deprecation),
-                kind: item_type.into(),
-                inner: from_clean_item_kind(kind, self.tcx),
-            }),
-        }
+        let inner = match *kind {
+            clean::StrippedItem(_) => return None,
+            x => from_clean_item_kind(x, self.tcx, &name),
+        };
+        Some(Item {
+            id: from_def_id(def_id),
+            crate_id: def_id.krate.as_u32(),
+            name: name.map(|sym| sym.to_string()),
+            source: self.convert_span(source),
+            visibility: self.convert_visibility(visibility),
+            docs: attrs.collapsed_doc_value(),
+            links: attrs
+                .links
+                .into_iter()
+                .filter_map(|clean::ItemLink { link, did, .. }| {
+                    did.map(|did| (link, from_def_id(did)))
+                })
+                .collect(),
+            attrs: attrs
+                .other_attrs
+                .iter()
+                .map(rustc_ast_pretty::pprust::attribute_to_string)
+                .collect(),
+            deprecation: deprecation.map(from_deprecation),
+            kind: item_type.into(),
+            inner,
+        })
     }
 
     fn convert_span(&self, span: clean::Span) -> Option<Span> {
@@ -149,13 +151,10 @@ crate fn from_def_id(did: DefId) -> Id {
     Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index)))
 }
 
-fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum {
+fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>, name: &Option<Symbol>) -> ItemEnum {
     use clean::ItemKind::*;
     match item {
         ModuleItem(m) => ItemEnum::ModuleItem(m.into()),
-        ExternCrateItem(c, a) => {
-            ItemEnum::ExternCrateItem { name: c.to_string(), rename: a.map(|x| x.to_string()) }
-        }
         ImportItem(i) => ItemEnum::ImportItem(i.into()),
         StructItem(s) => ItemEnum::StructItem(s.into()),
         UnionItem(u) => ItemEnum::UnionItem(u.into()),
@@ -182,10 +181,14 @@ fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum {
             bounds: g.into_iter().map(Into::into).collect(),
             default: t.map(Into::into),
         },
-        StrippedItem(inner) => from_clean_item_kind(*inner, tcx),
+        StrippedItem(inner) => from_clean_item_kind(*inner, tcx, name),
         PrimitiveItem(_) | KeywordItem(_) => {
             panic!("{:?} is not supported for JSON output", item)
         }
+        ExternCrateItem { ref src } => ItemEnum::ExternCrateItem {
+            name: name.as_ref().unwrap().to_string(),
+            rename: src.map(|x| x.to_string()),
+        },
     }
 }
 
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index e6edf33d23c..863610baed4 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -183,7 +183,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 match &*item.kind {
                     // These don't have names so they don't get added to the output by default
                     ImportItem(_) => self.item(item.clone()).unwrap(),
-                    ExternCrateItem(_, _) => self.item(item.clone()).unwrap(),
+                    ExternCrateItem { .. } => self.item(item.clone()).unwrap(),
                     ImplItem(i) => i.items.iter().for_each(|i| self.item(i.clone()).unwrap()),
                     _ => {}
                 }
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index bb54523871c..0e975128628 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -193,7 +193,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
                 // don't count items in stripped modules
                 return Some(i);
             }
-            clean::ImportItem(..) | clean::ExternCrateItem(..) => {
+            clean::ImportItem(..) | clean::ExternCrateItem { .. } => {
                 // docs on `use` and `extern crate` statements are not displayed, so they're not
                 // worth counting
                 return Some(i);
diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs
index ede9e18a511..2fa9179515d 100644
--- a/src/librustdoc/passes/doc_test_lints.rs
+++ b/src/librustdoc/passes/doc_test_lints.rs
@@ -63,7 +63,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
                 | clean::TypedefItem(_, _)
                 | clean::StaticItem(_)
                 | clean::ConstantItem(_)
-                | clean::ExternCrateItem(_, _)
+                | clean::ExternCrateItem { .. }
                 | clean::ImportItem(_)
                 | clean::PrimitiveItem(_)
                 | clean::KeywordItem(_)
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 162b70973b4..44d54563f27 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -66,7 +66,7 @@ impl<'a> DocFolder for Stripper<'a> {
             }
 
             // handled in the `strip-priv-imports` pass
-            clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
+            clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
 
             clean::ImplItem(..) => {}
 
@@ -161,7 +161,9 @@ crate struct ImportStripper;
 impl DocFolder for ImportStripper {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         match *i.kind {
-            clean::ExternCrateItem(..) | clean::ImportItem(..) if !i.visibility.is_public() => None,
+            clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => {
+                None
+            }
             _ => Some(self.fold_item_recur(i)),
         }
     }
diff --git a/src/test/codegen/issue-59352.rs b/src/test/codegen/issue-59352.rs
index 28bb8591232..d271fe027e3 100644
--- a/src/test/codegen/issue-59352.rs
+++ b/src/test/codegen/issue-59352.rs
@@ -5,8 +5,8 @@
 // Once the optimizer can do that, mir-opt/issues/issue-59352.rs will need to be updated and this
 // test case should be removed as it will become redundant.
 
-// mir-opt-level=2 enables inlining and enables LLVM to optimize away the unreachable panic call.
-// compile-flags: -O -Z mir-opt-level=2
+// mir-opt-level=3 enables inlining and enables LLVM to optimize away the unreachable panic call.
+// compile-flags: -O -Z mir-opt-level=3
 
 #![crate_type = "rlib"]
 
diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs
index 2a2208d4fce..d9e6f6c34ec 100644
--- a/src/test/codegen/naked-noinline.rs
+++ b/src/test/codegen/naked-noinline.rs
@@ -1,5 +1,5 @@
 // Checks that naked functions are never inlined.
-// compile-flags: -O -Zmir-opt-level=2
+// compile-flags: -O -Zmir-opt-level=3
 // ignore-wasm32
 #![crate_type = "lib"]
 #![feature(asm)]
diff --git a/src/test/codegen/sanitizer-no-sanitize-inlining.rs b/src/test/codegen/sanitizer-no-sanitize-inlining.rs
index be0547afa4c..f4af60baefe 100644
--- a/src/test/codegen/sanitizer-no-sanitize-inlining.rs
+++ b/src/test/codegen/sanitizer-no-sanitize-inlining.rs
@@ -4,8 +4,8 @@
 // needs-sanitizer-address
 // needs-sanitizer-leak
 // revisions: ASAN LSAN
-//[ASAN] compile-flags: -Zsanitizer=address -C opt-level=3 -Z mir-opt-level=3
-//[LSAN] compile-flags: -Zsanitizer=leak    -C opt-level=3 -Z mir-opt-level=3
+//[ASAN] compile-flags: -Zsanitizer=address -C opt-level=3 -Z mir-opt-level=4
+//[LSAN] compile-flags: -Zsanitizer=leak    -C opt-level=3 -Z mir-opt-level=4
 
 #![crate_type="lib"]
 #![feature(no_sanitize)]
diff --git a/src/test/codegen/try_identity.rs b/src/test/codegen/try_identity.rs
index d51bd575719..81e2435e5b8 100644
--- a/src/test/codegen/try_identity.rs
+++ b/src/test/codegen/try_identity.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=2 -Zunsound-mir-opts
+// compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=3 -Zunsound-mir-opts
 
 // Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering.
 // This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`.
diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs
index 6dae07dfbd1..57164e3e794 100644
--- a/src/test/mir-opt/const_prop/boolean_identities.rs
+++ b/src/test/mir-opt/const_prop/boolean_identities.rs
@@ -1,4 +1,4 @@
-// compile-flags: -O -Zmir-opt-level=3
+// compile-flags: -O -Zmir-opt-level=4
 
 // EMIT_MIR boolean_identities.test.ConstProp.diff
 pub fn test(x: bool, y: bool) -> bool {
diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue-66971.rs
index 986177b5c0a..81eccae46b9 100644
--- a/src/test/mir-opt/const_prop/issue-66971.rs
+++ b/src/test/mir-opt/const_prop/issue-66971.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 
 // Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
 // outputs below, after ConstProp this is how _2 would look like with the bug:
diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue-67019.rs
index d277bd5869c..c78b8b97178 100644
--- a/src/test/mir-opt/const_prop/issue-67019.rs
+++ b/src/test/mir-opt/const_prop/issue-67019.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 
 // This used to ICE in const-prop
 
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs
index 1cb50155b5e..b0ecdf1818e 100644
--- a/src/test/mir-opt/const_prop/mult_by_zero.rs
+++ b/src/test/mir-opt/const_prop/mult_by_zero.rs
@@ -1,4 +1,4 @@
-// compile-flags: -O -Zmir-opt-level=3
+// compile-flags: -O -Zmir-opt-level=4
 
 // EMIT_MIR mult_by_zero.test.ConstProp.diff
 fn test(x : i32) -> i32 {
diff --git a/src/test/mir-opt/early_otherwise_branch.rs b/src/test/mir-opt/early_otherwise_branch.rs
index 77003442080..548213ab83c 100644
--- a/src/test/mir-opt/early_otherwise_branch.rs
+++ b/src/test/mir-opt/early_otherwise_branch.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 // EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
 fn opt1(x: Option<u32>, y: Option<u32>) -> u32 {
     match (x, y) {
diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs
index 1d6877d67df..aa304f747f7 100644
--- a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs
+++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 
 // EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
 fn opt1(x: Option<u32>, y: Option<u32>, z: Option<u32>) -> u32 {
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.rs b/src/test/mir-opt/early_otherwise_branch_68867.rs
index b822c58f550..e11337643da 100644
--- a/src/test/mir-opt/early_otherwise_branch_68867.rs
+++ b/src/test/mir-opt/early_otherwise_branch_68867.rs
@@ -1,5 +1,5 @@
 // ignore-tidy-linelength
-// compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
+// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
 
 // example from #68867
 type CSSFloat = f32;
diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.rs b/src/test/mir-opt/early_otherwise_branch_noopt.rs
index bd15f520dfc..aa9ddf485b5 100644
--- a/src/test/mir-opt/early_otherwise_branch_noopt.rs
+++ b/src/test/mir-opt/early_otherwise_branch_noopt.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 
 // must not optimize as it does not follow the pattern of
 // left and right hand side being the same variant
diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs
index 57298605b18..049a97816f6 100644
--- a/src/test/mir-opt/inline/inline-into-box-place.rs
+++ b/src/test/mir-opt/inline/inline-into-box-place.rs
@@ -1,6 +1,6 @@
 // ignore-endian-big
 // ignore-wasm32-bare compiled with panic=abort by default
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 #![feature(box_syntax)]
 // EMIT_MIR inline_into_box_place.main.Inline.diff
diff --git a/src/test/mir-opt/inline/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline-trait-method_2.rs
index 6e5de8315a1..378e71a2567 100644
--- a/src/test/mir-opt/inline/inline-trait-method_2.rs
+++ b/src/test/mir-opt/inline/inline-trait-method_2.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z span_free_formats -Z mir-opt-level=3
+// compile-flags: -Z span_free_formats -Z mir-opt-level=4
 
 // EMIT_MIR inline_trait_method_2.test2.Inline.after.mir
 fn test2(x: &dyn X) -> bool {
diff --git a/src/test/mir-opt/issues/issue-59352.rs b/src/test/mir-opt/issues/issue-59352.rs
index 9e59337a01d..1e0045555ab 100644
--- a/src/test/mir-opt/issues/issue-59352.rs
+++ b/src/test/mir-opt/issues/issue-59352.rs
@@ -7,7 +7,7 @@
 // removed.
 
 // EMIT_MIR issue_59352.num_to_digit.PreCodegen.after.mir
-// compile-flags: -Z mir-opt-level=2 -Z span_free_formats
+// compile-flags: -Z mir-opt-level=3 -Z span_free_formats
 
 pub fn num_to_digit(num: char) -> u32 {
     // CHECK-NOT: panic
diff --git a/src/test/mir-opt/multiple_return_terminators.rs b/src/test/mir-opt/multiple_return_terminators.rs
index b73a51d4835..a2b902d1483 100644
--- a/src/test/mir-opt/multiple_return_terminators.rs
+++ b/src/test/mir-opt/multiple_return_terminators.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 // EMIT_MIR multiple_return_terminators.test.MultipleReturnTerminators.diff
 
 fn test(x: bool) {
diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify-arm-identity.rs
index 0a59032e87b..bedc86bbacb 100644
--- a/src/test/mir-opt/simplify-arm-identity.rs
+++ b/src/test/mir-opt/simplify-arm-identity.rs
@@ -1,7 +1,7 @@
 // Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts.
 // Regression test for issue #66856.
 //
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 
 enum Src {
diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify-arm.rs
index a7df786357b..50b5147e0cf 100644
--- a/src/test/mir-opt/simplify-arm.rs
+++ b/src/test/mir-opt/simplify-arm.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2 -Zunsound-mir-opts
+// compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
 // EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff
 // EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff
 // EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff
diff --git a/src/test/rustdoc-ui/doc-attr.rs b/src/test/rustdoc-ui/doc-attr.rs
index 3519b5707b3..3a584112973 100644
--- a/src/test/rustdoc-ui/doc-attr.rs
+++ b/src/test/rustdoc-ui/doc-attr.rs
@@ -1,11 +1,10 @@
 #![crate_type = "lib"]
-#![deny(unused_attributes)]
-//~^ NOTE lint level is defined here
+#![deny(warnings)]
 #![doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~| WARNING will become a hard error in a future release
+//~^^ WARN
 
 #[doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~| WARNING will become a hard error in a future release
+//~^^ WARN
 pub fn foo() {}
diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr
index 9666db2b10e..21479d25fc2 100644
--- a/src/test/rustdoc-ui/doc-attr.stderr
+++ b/src/test/rustdoc-ui/doc-attr.stderr
@@ -1,5 +1,5 @@
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:8:7
+  --> $DIR/doc-attr.rs:7:7
    |
 LL | #[doc(as_ptr)]
    |       ^^^^^^
@@ -7,17 +7,20 @@ LL | #[doc(as_ptr)]
 note: the lint level is defined here
   --> $DIR/doc-attr.rs:2:9
    |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:4:8
+  --> $DIR/doc-attr.rs:3:8
    |
 LL | #![doc(as_ptr)]
    |        ^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/rustdoc-ui/doc-attr2.rs b/src/test/rustdoc-ui/doc-attr2.rs
new file mode 100644
index 00000000000..3fb484644d7
--- /dev/null
+++ b/src/test/rustdoc-ui/doc-attr2.rs
@@ -0,0 +1,11 @@
+#![crate_type = "lib"]
+#![deny(warnings)]
+
+#[doc(test(no_crate_inject))] //~ ERROR
+//~^ WARN
+pub fn foo() {}
+
+pub mod bar {
+    #![doc(test(no_crate_inject))] //~ ERROR
+    //~^ WARN
+}
diff --git a/src/test/rustdoc-ui/doc-attr2.stderr b/src/test/rustdoc-ui/doc-attr2.stderr
new file mode 100644
index 00000000000..eeb2c2be085
--- /dev/null
+++ b/src/test/rustdoc-ui/doc-attr2.stderr
@@ -0,0 +1,26 @@
+error: `#![doc(test(...)]` is only allowed as a crate level attribute
+  --> $DIR/doc-attr2.rs:4:7
+   |
+LL | #[doc(test(no_crate_inject))]
+   |       ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/doc-attr2.rs:2:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: `#![doc(test(...)]` is only allowed as a crate level attribute
+  --> $DIR/doc-attr2.rs:9:12
+   |
+LL |     #![doc(test(no_crate_inject))]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/attributes/doc-attr.rs b/src/test/ui/attributes/doc-attr.rs
index 3519b5707b3..3a584112973 100644
--- a/src/test/ui/attributes/doc-attr.rs
+++ b/src/test/ui/attributes/doc-attr.rs
@@ -1,11 +1,10 @@
 #![crate_type = "lib"]
-#![deny(unused_attributes)]
-//~^ NOTE lint level is defined here
+#![deny(warnings)]
 #![doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~| WARNING will become a hard error in a future release
+//~^^ WARN
 
 #[doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~| WARNING will become a hard error in a future release
+//~^^ WARN
 pub fn foo() {}
diff --git a/src/test/ui/attributes/doc-attr.stderr b/src/test/ui/attributes/doc-attr.stderr
index 9666db2b10e..21479d25fc2 100644
--- a/src/test/ui/attributes/doc-attr.stderr
+++ b/src/test/ui/attributes/doc-attr.stderr
@@ -1,5 +1,5 @@
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:8:7
+  --> $DIR/doc-attr.rs:7:7
    |
 LL | #[doc(as_ptr)]
    |       ^^^^^^
@@ -7,17 +7,20 @@ LL | #[doc(as_ptr)]
 note: the lint level is defined here
   --> $DIR/doc-attr.rs:2:9
    |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:4:8
+  --> $DIR/doc-attr.rs:3:8
    |
 LL | #![doc(as_ptr)]
    |        ^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/attributes/doc-attr2.rs b/src/test/ui/attributes/doc-attr2.rs
new file mode 100644
index 00000000000..3fb484644d7
--- /dev/null
+++ b/src/test/ui/attributes/doc-attr2.rs
@@ -0,0 +1,11 @@
+#![crate_type = "lib"]
+#![deny(warnings)]
+
+#[doc(test(no_crate_inject))] //~ ERROR
+//~^ WARN
+pub fn foo() {}
+
+pub mod bar {
+    #![doc(test(no_crate_inject))] //~ ERROR
+    //~^ WARN
+}
diff --git a/src/test/ui/attributes/doc-attr2.stderr b/src/test/ui/attributes/doc-attr2.stderr
new file mode 100644
index 00000000000..eeb2c2be085
--- /dev/null
+++ b/src/test/ui/attributes/doc-attr2.stderr
@@ -0,0 +1,26 @@
+error: `#![doc(test(...)]` is only allowed as a crate level attribute
+  --> $DIR/doc-attr2.rs:4:7
+   |
+LL | #[doc(test(no_crate_inject))]
+   |       ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/doc-attr2.rs:2:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: `#![doc(test(...)]` is only allowed as a crate level attribute
+  --> $DIR/doc-attr2.rs:9:12
+   |
+LL |     #![doc(test(no_crate_inject))]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/issues/issue-75299.rs b/src/test/ui/const-generics/issues/issue-75299.rs
index 23f30a1eea0..9d3f25b3b47 100644
--- a/src/test/ui/const-generics/issues/issue-75299.rs
+++ b/src/test/ui/const-generics/issues/issue-75299.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Zmir-opt-level=3
+// compile-flags: -Zmir-opt-level=4
 // run-pass
 
 #![feature(const_generics)]
diff --git a/src/test/ui/const_prop/inline_spans.rs b/src/test/ui/const_prop/inline_spans.rs
index 32902b49d02..adc7874104a 100644
--- a/src/test/ui/const_prop/inline_spans.rs
+++ b/src/test/ui/const_prop/inline_spans.rs
@@ -1,5 +1,5 @@
 // build-fail
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 
 #![deny(warnings)]
 
diff --git a/src/test/ui/const_prop/inline_spans_lint_attribute.rs b/src/test/ui/const_prop/inline_spans_lint_attribute.rs
index 656ff02dc67..1db53d77193 100644
--- a/src/test/ui/const_prop/inline_spans_lint_attribute.rs
+++ b/src/test/ui/const_prop/inline_spans_lint_attribute.rs
@@ -1,6 +1,6 @@
 // Must be build-pass, because check-pass will not run const prop and thus not emit the lint anyway.
 // build-pass
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 
 #![deny(warnings)]
 
diff --git a/src/test/ui/consts/issue-66345.rs b/src/test/ui/consts/issue-66345.rs
index 7d0de73007c..4971d96476f 100644
--- a/src/test/ui/consts/issue-66345.rs
+++ b/src/test/ui/consts/issue-66345.rs
@@ -1,8 +1,8 @@
 // run-pass
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 
 // Checks that the compiler does not ICE when passing references to field of by-value struct
-// with -Z mir-opt-level=3
+// with -Z mir-opt-level=4
 
 fn do_nothing(_: &()) {}
 
diff --git a/src/test/ui/consts/issue-67529.rs b/src/test/ui/consts/issue-67529.rs
index df4bc668bee..dd24c2d27e2 100644
--- a/src/test/ui/consts/issue-67529.rs
+++ b/src/test/ui/consts/issue-67529.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // run-pass
 
 struct Baz<T: ?Sized> {
diff --git a/src/test/ui/consts/issue-67640.rs b/src/test/ui/consts/issue-67640.rs
index bc0ee8d386f..4c71a2e0224 100644
--- a/src/test/ui/consts/issue-67640.rs
+++ b/src/test/ui/consts/issue-67640.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 // run-pass
 
 struct X {
diff --git a/src/test/ui/consts/issue-67641.rs b/src/test/ui/consts/issue-67641.rs
index f50fba287a2..e5a74f15654 100644
--- a/src/test/ui/consts/issue-67641.rs
+++ b/src/test/ui/consts/issue-67641.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // run-pass
 
 use std::cell::Cell;
diff --git a/src/test/ui/consts/issue-67862.rs b/src/test/ui/consts/issue-67862.rs
index 84f72154d26..b9e96a87f14 100644
--- a/src/test/ui/consts/issue-67862.rs
+++ b/src/test/ui/consts/issue-67862.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // run-pass
 
 fn e220() -> (i64, i64) {
diff --git a/src/test/ui/consts/trait_specialization.rs b/src/test/ui/consts/trait_specialization.rs
index 3adbbb53046..c581ef6b0f7 100644
--- a/src/test/ui/consts/trait_specialization.rs
+++ b/src/test/ui/consts/trait_specialization.rs
@@ -1,5 +1,5 @@
 // ignore-wasm32-bare which doesn't support `std::process:exit()`
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 // run-pass
 
 // Tests that specialization does not cause optimizations running on polymorphic MIR to resolve
diff --git a/src/test/ui/dest-prop/skeptic-miscompile.rs b/src/test/ui/dest-prop/skeptic-miscompile.rs
index c27a1f04532..4bb61dbc7f4 100644
--- a/src/test/ui/dest-prop/skeptic-miscompile.rs
+++ b/src/test/ui/dest-prop/skeptic-miscompile.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 
 trait IterExt: Iterator {
     fn fold_ex<B, F>(mut self, init: B, mut f: F) -> B
diff --git a/src/test/ui/issues/issue-50411.rs b/src/test/ui/issues/issue-50411.rs
index 1bf12707817..cd728b15256 100644
--- a/src/test/ui/issues/issue-50411.rs
+++ b/src/test/ui/issues/issue-50411.rs
@@ -3,7 +3,7 @@
 // elaborate-drops invoked on it) and then try to elaboate drops a
 // second time. Uncool.
 
-// compile-flags:-Zmir-opt-level=3
+// compile-flags:-Zmir-opt-level=4
 // build-pass
 
 fn main() {
diff --git a/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs b/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs
index fb4bf2b8b44..1e20a546069 100644
--- a/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs
+++ b/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs
@@ -1,5 +1,5 @@
 // revisions: default miropt
-//[miropt]compile-flags: -Z mir-opt-level=2
+//[miropt]compile-flags: -Z mir-opt-level=3
 // ~^ This flag is for #77668, it used to be ICE.
 
 #![crate_type = "lib"]
diff --git a/src/test/ui/issues/issue-77002.rs b/src/test/ui/issues/issue-77002.rs
index c7dd3cf8109..0c37346eaf8 100644
--- a/src/test/ui/issues/issue-77002.rs
+++ b/src/test/ui/issues/issue-77002.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Zmir-opt-level=2 -Copt-level=0
+// compile-flags: -Zmir-opt-level=3 -Copt-level=0
 // run-pass
 
 type M = [i64; 2];
diff --git a/src/test/ui/mir/auxiliary/issue_76375_aux.rs b/src/test/ui/mir/auxiliary/issue_76375_aux.rs
index 72f32ecf7ea..90f4df739f1 100644
--- a/src/test/ui/mir/auxiliary/issue_76375_aux.rs
+++ b/src/test/ui/mir/auxiliary/issue_76375_aux.rs
@@ -1,5 +1,5 @@
 // edition:2018
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 
 #[inline(always)]
 pub fn copy_prop(s: bool) -> String {
diff --git a/src/test/ui/mir/issue-66851.rs b/src/test/ui/mir/issue-66851.rs
index 72d62a30a33..878ad4e475a 100644
--- a/src/test/ui/mir/issue-66851.rs
+++ b/src/test/ui/mir/issue-66851.rs
@@ -2,7 +2,7 @@
 // did not check that the types matched up in the `Ok(r)` branch.
 //
 // run-pass
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 
 #[derive(Debug, PartialEq, Eq)]
 enum SpecialsRes { Res(u64) }
diff --git a/src/test/ui/mir/issue-67639-normalization-ice.rs b/src/test/ui/mir/issue-67639-normalization-ice.rs
index 21851a72525..71150a80bc0 100644
--- a/src/test/ui/mir/issue-67639-normalization-ice.rs
+++ b/src/test/ui/mir/issue-67639-normalization-ice.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 // build-pass
 
 // This used to ICE in const-prop due
diff --git a/src/test/ui/mir/issue-67710-inline-projection.rs b/src/test/ui/mir/issue-67710-inline-projection.rs
index 37d8f2eac9b..1ff6b4d628c 100644
--- a/src/test/ui/mir/issue-67710-inline-projection.rs
+++ b/src/test/ui/mir/issue-67710-inline-projection.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // build-pass
 
 // This used to ICE due to the inling pass not examining projections
diff --git a/src/test/ui/mir/issue-68841.rs b/src/test/ui/mir/issue-68841.rs
index 14884a97fab..550bd452a80 100644
--- a/src/test/ui/mir/issue-68841.rs
+++ b/src/test/ui/mir/issue-68841.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // edition:2018
 // build-pass
 
diff --git a/src/test/ui/mir/issue-71793-inline-args-storage.rs b/src/test/ui/mir/issue-71793-inline-args-storage.rs
index 87b2806d4e2..18f2e38d14c 100644
--- a/src/test/ui/mir/issue-71793-inline-args-storage.rs
+++ b/src/test/ui/mir/issue-71793-inline-args-storage.rs
@@ -4,7 +4,7 @@
 //
 // check-pass
 // edition:2018
-// compile-args: -Zmir-opt-level=2
+// compile-args: -Zmir-opt-level=3
 
 #![crate_type = "lib"]
 
diff --git a/src/test/ui/mir/issue-75053.rs b/src/test/ui/mir/issue-75053.rs
index 6e7211c2ee6..d54e23169c4 100644
--- a/src/test/ui/mir/issue-75053.rs
+++ b/src/test/ui/mir/issue-75053.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // build-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/mir/issue-76248.rs b/src/test/ui/mir/issue-76248.rs
index b01a9727852..18473e79e86 100644
--- a/src/test/ui/mir/issue-76248.rs
+++ b/src/test/ui/mir/issue-76248.rs
@@ -3,7 +3,7 @@
 // Regression test for #76248.
 //
 // build-pass
-// compile-flags: -Zmir-opt-level=2
+// compile-flags: -Zmir-opt-level=3
 
 const N: usize = 1;
 
diff --git a/src/test/ui/mir/issue-76375.rs b/src/test/ui/mir/issue-76375.rs
index a7772cb1fe6..e635caca9fd 100644
--- a/src/test/ui/mir/issue-76375.rs
+++ b/src/test/ui/mir/issue-76375.rs
@@ -2,7 +2,7 @@
 //
 // edition:2018
 // build-pass
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // aux-build:issue_76375_aux.rs
 
 #![crate_type = "lib"]
diff --git a/src/test/ui/mir/issue-76740-copy-propagation.rs b/src/test/ui/mir/issue-76740-copy-propagation.rs
index 90999a3e556..1d4ec11762a 100644
--- a/src/test/ui/mir/issue-76740-copy-propagation.rs
+++ b/src/test/ui/mir/issue-76740-copy-propagation.rs
@@ -1,6 +1,6 @@
 // Regression test for issue #76740.
 // run-pass
-// compile-flags: -Zmir-opt-level=3
+// compile-flags: -Zmir-opt-level=4
 
 #[derive(Copy, Clone)]
 pub struct V([usize; 4]);
diff --git a/src/test/ui/mir/issue-77911.rs b/src/test/ui/mir/issue-77911.rs
index fff303495e7..acf4c20542d 100644
--- a/src/test/ui/mir/issue-77911.rs
+++ b/src/test/ui/mir/issue-77911.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // build-pass
 
 use std::fs::File;
diff --git a/src/test/ui/mir/issue-78496.rs b/src/test/ui/mir/issue-78496.rs
index 1b0687cfac3..a0d1f5a780e 100644
--- a/src/test/ui/mir/issue-78496.rs
+++ b/src/test/ui/mir/issue-78496.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags: -Z mir-opt-level=2 -C opt-level=0
+// compile-flags: -Z mir-opt-level=3 -C opt-level=0
 
 // example from #78496
 pub enum E<'a> {
diff --git a/src/test/ui/mir/issue66339.rs b/src/test/ui/mir/issue66339.rs
index 98e178c0551..2507af38cdf 100644
--- a/src/test/ui/mir/issue66339.rs
+++ b/src/test/ui/mir/issue66339.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // build-pass
 
 // This used to ICE in const-prop
diff --git a/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs b/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs
index eec0a4599c3..e36e8bd746d 100644
--- a/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs
+++ b/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs
@@ -2,7 +2,7 @@
 // Regression test for issue #79269.
 //
 // build-pass
-// compile-flags: -Zmir-opt-level=2 -Zvalidate-mir
+// compile-flags: -Zmir-opt-level=3 -Zvalidate-mir
 #[derive(Clone)]
 struct Array<T, const N: usize>([T; N]);
 
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-45493.rs b/src/test/ui/mir/mir-inlining/ice-issue-45493.rs
index 1bd16dc43e1..04a23212e7b 100644
--- a/src/test/ui/mir/mir-inlining/ice-issue-45493.rs
+++ b/src/test/ui/mir/mir-inlining/ice-issue-45493.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 
 trait Array {
     type Item;
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-45885.rs b/src/test/ui/mir/mir-inlining/ice-issue-45885.rs
index e930a4d1ccd..09b1279ef34 100644
--- a/src/test/ui/mir/mir-inlining/ice-issue-45885.rs
+++ b/src/test/ui/mir/mir-inlining/ice-issue-45885.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 
 pub enum Enum {
     A,
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-68347.rs b/src/test/ui/mir/mir-inlining/ice-issue-68347.rs
index 88b80bc3333..7c135250940 100644
--- a/src/test/ui/mir/mir-inlining/ice-issue-68347.rs
+++ b/src/test/ui/mir/mir-inlining/ice-issue-68347.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 pub fn main() {
     let _x: fn() = handle_debug_column;
 }
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-77306-1.rs b/src/test/ui/mir/mir-inlining/ice-issue-77306-1.rs
index 4d083bf2321..ef05ff9ce03 100644
--- a/src/test/ui/mir/mir-inlining/ice-issue-77306-1.rs
+++ b/src/test/ui/mir/mir-inlining/ice-issue-77306-1.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 
 // Previously ICEd because we did not normalize during inlining,
 // see https://github.com/rust-lang/rust/pull/77306 for more discussion.
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-77306-2.rs b/src/test/ui/mir/mir-inlining/ice-issue-77306-2.rs
index a346d450586..cb208401313 100644
--- a/src/test/ui/mir/mir-inlining/ice-issue-77306-2.rs
+++ b/src/test/ui/mir/mir-inlining/ice-issue-77306-2.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 
 struct Cursor {}
 struct TokenTree {}
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-77564.rs b/src/test/ui/mir/mir-inlining/ice-issue-77564.rs
index 262402df2cc..0d3fbfe5d1a 100644
--- a/src/test/ui/mir/mir-inlining/ice-issue-77564.rs
+++ b/src/test/ui/mir/mir-inlining/ice-issue-77564.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 
 use std::mem::MaybeUninit;
 const N: usize = 2;
diff --git a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs b/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs
index 2437155d981..8ed7f25d2bb 100644
--- a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs
+++ b/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs
@@ -1,9 +1,9 @@
-// Ensures -Zmir-opt-level=2 (specifically, inlining) is not allowed with -Zinstrument-coverage.
+// Ensures -Zmir-opt-level=3 (specifically, inlining) is not allowed with -Zinstrument-coverage.
 // Regression test for issue #80060.
 //
 // needs-profiler-support
 // build-pass
-// compile-flags: -Zmir-opt-level=2 -Zinstrument-coverage
+// compile-flags: -Zmir-opt-level=3 -Zinstrument-coverage
 #[inline(never)]
 fn foo() {}
 
diff --git a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr b/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr
index eb50e5075ca..d482afc395d 100644
--- a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr
+++ b/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr
@@ -1,2 +1,2 @@
-warning: `-Z mir-opt-level=2` (or any level > 1) enables function inlining, which is incompatible with `-Z instrument-coverage`. Inlining will be disabled.
+warning: `-Z mir-opt-level=3` (or any level > 1) enables function inlining, which is incompatible with `-Z instrument-coverage`. Inlining will be disabled.
 
diff --git a/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs b/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs
index 8f570dbd4ad..8b3cb703dc0 100644
--- a/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs
+++ b/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags:-Zmir-opt-level=2
+// compile-flags:-Zmir-opt-level=3
 pub trait Foo {
     fn bar(&self) -> usize { 2 }
 }
diff --git a/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs b/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs
index 23cc114880c..e2620682679 100644
--- a/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs
+++ b/src/test/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags: -Z mir-opt-level=2 -C opt-level=0 -C debuginfo=2
+// compile-flags: -Z mir-opt-level=3 -C opt-level=0 -C debuginfo=2
 
 #[inline(never)]
 pub fn foo(bar: usize) -> usize {
diff --git a/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs b/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs
index 629b50dec65..b66a85d07d3 100644
--- a/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs
+++ b/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=2
+// compile-flags: -Z mir-opt-level=3
 // build-pass
 #![crate_type="lib"]
 
diff --git a/src/test/ui/mir/ssa-analysis-regression-50041.rs b/src/test/ui/mir/ssa-analysis-regression-50041.rs
index c818f2976e1..1892807253a 100644
--- a/src/test/ui/mir/ssa-analysis-regression-50041.rs
+++ b/src/test/ui/mir/ssa-analysis-regression-50041.rs
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags: -Z mir-opt-level=3
+// compile-flags: -Z mir-opt-level=4
 
 #![crate_type="lib"]
 #![feature(lang_items)]
diff --git a/src/test/ui/parser/match-arm-without-braces.rs b/src/test/ui/parser/match-arm-without-braces.rs
new file mode 100644
index 00000000000..55a88742769
--- /dev/null
+++ b/src/test/ui/parser/match-arm-without-braces.rs
@@ -0,0 +1,87 @@
+struct S;
+
+impl S {
+    fn get<K, V: Default>(_: K) -> Option<V> {
+        Default::default()
+    }
+}
+
+enum Val {
+    Foo,
+    Bar,
+}
+
+impl Default for Val {
+    fn default() -> Self {
+        Val::Foo
+    }
+}
+
+fn main() {
+    match S::get(1) {
+        Some(Val::Foo) => {}
+        _ => {}
+    }
+    match S::get(2) {
+        Some(Val::Foo) => 3; //~ ERROR `match` arm body without braces
+        _ => 4,
+    }
+    match S::get(5) {
+        Some(Val::Foo) =>
+          7; //~ ERROR `match` arm body without braces
+          8;
+        _ => 9,
+    }
+    match S::get(10) {
+        Some(Val::Foo) =>
+          11; //~ ERROR `match` arm body without braces
+          12;
+        _ => (),
+    }
+    match S::get(13) {
+        None => {}
+        Some(Val::Foo) =>
+          14; //~ ERROR `match` arm body without braces
+          15;
+    }
+    match S::get(16) {
+        Some(Val::Foo) => 17
+        _ => 18, //~ ERROR expected one of
+    }
+    match S::get(19) {
+        Some(Val::Foo) =>
+          20; //~ ERROR `match` arm body without braces
+          21
+        _ => 22,
+    }
+    match S::get(23) {
+        Some(Val::Foo) =>
+          24; //~ ERROR `match` arm body without braces
+          25
+        _ => (),
+    }
+    match S::get(26) {
+        None => {}
+        Some(Val::Foo) =>
+          27; //~ ERROR `match` arm body without braces
+          28
+    }
+    match S::get(29) {
+        Some(Val::Foo) =>
+          30; //~ ERROR expected one of
+          31,
+        _ => 32,
+    }
+    match S::get(33) {
+        Some(Val::Foo) =>
+          34; //~ ERROR expected one of
+          35,
+        _ => (),
+    }
+    match S::get(36) {
+        None => {}
+        Some(Val::Foo) =>
+          37; //~ ERROR expected one of
+          38,
+    }
+}
diff --git a/src/test/ui/parser/match-arm-without-braces.stderr b/src/test/ui/parser/match-arm-without-braces.stderr
new file mode 100644
index 00000000000..03ae351bf79
--- /dev/null
+++ b/src/test/ui/parser/match-arm-without-braces.stderr
@@ -0,0 +1,135 @@
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:26:27
+   |
+LL |         Some(Val::Foo) => 3;
+   |                        -- ^- help: use a comma to end a `match` arm expression: `,`
+   |                        |  |
+   |                        |  this statement is not surrounded by a body
+   |                        while parsing the `match` arm starting here
+
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:31:11
+   |
+LL |           Some(Val::Foo) =>
+   |                          -- while parsing the `match` arm starting here
+LL | /           7;
+LL | |           8;
+   | |____________^ these statements are not surrounded by a body
+   |
+help: surround the statements with a body
+   |
+LL |           { 7;
+LL |           8; }
+   |
+
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:37:11
+   |
+LL |           Some(Val::Foo) =>
+   |                          -- while parsing the `match` arm starting here
+LL | /           11;
+LL | |           12;
+   | |_____________^ these statements are not surrounded by a body
+   |
+help: surround the statements with a body
+   |
+LL |           { 11;
+LL |           12; }
+   |
+
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:44:11
+   |
+LL |           Some(Val::Foo) =>
+   |                          -- while parsing the `match` arm starting here
+LL | /           14;
+LL | |           15;
+   | |_____________^ these statements are not surrounded by a body
+   |
+help: surround the statements with a body
+   |
+LL |           { 14;
+LL |           15; }
+   |
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found reserved identifier `_`
+  --> $DIR/match-arm-without-braces.rs:49:9
+   |
+LL |         Some(Val::Foo) => 17
+   |                        --   - expected one of `,`, `.`, `?`, `}`, or an operator
+   |                        |
+   |                        while parsing the `match` arm starting here
+LL |         _ => 18,
+   |         ^ unexpected token
+
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:53:11
+   |
+LL |           Some(Val::Foo) =>
+   |                          -- while parsing the `match` arm starting here
+LL | /           20;
+LL | |           21
+   | |____________^ these statements are not surrounded by a body
+   |
+help: surround the statements with a body
+   |
+LL |           { 20;
+LL |           21 }
+   |
+
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:59:11
+   |
+LL |           Some(Val::Foo) =>
+   |                          -- while parsing the `match` arm starting here
+LL | /           24;
+LL | |           25
+   | |____________^ these statements are not surrounded by a body
+   |
+help: surround the statements with a body
+   |
+LL |           { 24;
+LL |           25 }
+   |
+
+error: `match` arm body without braces
+  --> $DIR/match-arm-without-braces.rs:66:11
+   |
+LL |           Some(Val::Foo) =>
+   |                          -- while parsing the `match` arm starting here
+LL | /           27;
+LL | |           28
+   | |____________^ these statements are not surrounded by a body
+   |
+help: surround the statements with a body
+   |
+LL |           { 27;
+LL |           28 }
+   |
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
+  --> $DIR/match-arm-without-braces.rs:71:13
+   |
+LL |         Some(Val::Foo) =>
+   |                        -- while parsing the `match` arm starting here
+LL |           30;
+   |             ^ expected one of `,`, `.`, `?`, `}`, or an operator
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
+  --> $DIR/match-arm-without-braces.rs:77:13
+   |
+LL |         Some(Val::Foo) =>
+   |                        -- while parsing the `match` arm starting here
+LL |           34;
+   |             ^ expected one of `,`, `.`, `?`, `}`, or an operator
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
+  --> $DIR/match-arm-without-braces.rs:84:13
+   |
+LL |         Some(Val::Foo) =>
+   |                        -- while parsing the `match` arm starting here
+LL |           37;
+   |             ^ expected one of `,`, `.`, `?`, `}`, or an operator
+
+error: aborting due to 11 previous errors
+
diff --git a/src/test/ui/polymorphization/promoted-function-3.rs b/src/test/ui/polymorphization/promoted-function-3.rs
index 1c84df13e10..bbd991e36cc 100644
--- a/src/test/ui/polymorphization/promoted-function-3.rs
+++ b/src/test/ui/polymorphization/promoted-function-3.rs
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags: -Zpolymorphize=on -Zmir-opt-level=3
+// compile-flags: -Zpolymorphize=on -Zmir-opt-level=4
 
 fn caller<T, U>() -> &'static usize {
     callee::<U>()
diff --git a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
index b2ed8a0d7da..e5754d355d9 100644
--- a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
+++ b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 #[inline(never)]
 #[track_caller]
diff --git a/src/test/ui/rfc-2091-track-caller/const-caller-location.rs b/src/test/ui/rfc-2091-track-caller/const-caller-location.rs
index 89a42acafba..89b0b69f38d 100644
--- a/src/test/ui/rfc-2091-track-caller/const-caller-location.rs
+++ b/src/test/ui/rfc-2091-track-caller/const-caller-location.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 #![feature(const_caller_location, const_fn)]
 
diff --git a/src/test/ui/rfc-2091-track-caller/intrinsic-wrapper.rs b/src/test/ui/rfc-2091-track-caller/intrinsic-wrapper.rs
index d072fb76f10..87e52881c15 100644
--- a/src/test/ui/rfc-2091-track-caller/intrinsic-wrapper.rs
+++ b/src/test/ui/rfc-2091-track-caller/intrinsic-wrapper.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 macro_rules! caller_location_from_macro {
     () => (core::panic::Location::caller());
diff --git a/src/test/ui/rfc-2091-track-caller/pass.rs b/src/test/ui/rfc-2091-track-caller/pass.rs
index 4d548d4f0aa..1b13ea3e93c 100644
--- a/src/test/ui/rfc-2091-track-caller/pass.rs
+++ b/src/test/ui/rfc-2091-track-caller/pass.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 #[track_caller]
 fn f() {}
diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
index 0d7a5c42532..84b7c6701e5 100644
--- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
+++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
@@ -1,7 +1,7 @@
 // run-pass
 // ignore-wasm32-bare compiled with panic=abort by default
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 #![feature(option_expect_none, option_unwrap_none)]
 #![allow(unconditional_panic)]
diff --git a/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs b/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs
index 43135ebbf65..9d28eb9de09 100644
--- a/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs
+++ b/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 use std::panic::Location;
 
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
index 2122a4ca219..65881257815 100644
--- a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
+++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 fn pass_to_ptr_call<T>(f: fn(T), x: T) {
     f(x);
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
index 922d2d7b702..8bb4dd288f0 100644
--- a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
+++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
@@ -1,6 +1,6 @@
 // run-pass
 // revisions: default mir-opt
-//[mir-opt] compile-flags: -Zmir-opt-level=3
+//[mir-opt] compile-flags: -Zmir-opt-level=4
 
 fn ptr_call(f: fn()) {
     f();
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs
index 4c09ae25c5f..4be68183050 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs
@@ -2,7 +2,7 @@
 // passed the wrong Instance, causing issues with inlining. See #67557.
 //
 // run-pass
-// compile-flags: -Zmir-opt-level=3
+// compile-flags: -Zmir-opt-level=4
 #![feature(platform_intrinsics, repr_simd)]
 
 extern "platform-intrinsic" {
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs
index 7a0d955686b..67556829815 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs
@@ -2,7 +2,7 @@
 // the wrong Instance, causing issues with inlining. See #67557.
 //
 // run-pass
-// compile-flags: -Zmir-opt-level=3
+// compile-flags: -Zmir-opt-level=4
 #![feature(platform_intrinsics, repr_simd)]
 
 extern "platform-intrinsic" {
diff --git a/src/test/ui/structs/80853.rs b/src/test/ui/structs/issue-80853.rs
index 242d0af959d..242d0af959d 100644
--- a/src/test/ui/structs/80853.rs
+++ b/src/test/ui/structs/issue-80853.rs
diff --git a/src/test/ui/structs/80853.stderr b/src/test/ui/structs/issue-80853.stderr
index 8a38e32c1d0..1c7d52b6d60 100644
--- a/src/test/ui/structs/80853.stderr
+++ b/src/test/ui/structs/issue-80853.stderr
@@ -1,5 +1,5 @@
 error[E0618]: expected function, found `S`
-  --> $DIR/80853.rs:4:5
+  --> $DIR/issue-80853.rs:4:5
    |
 LL | fn repro_ref(thing: S) {
    |              ----- `thing` has type `S`
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index d5143e1438e..94af21568ee 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -83,7 +83,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
         // run on the unoptimized MIR. On the other hand this results in some false negatives. If
         // MIR passes can be enabled / disabled separately, we should figure out, what passes to
         // use for Clippy.
-        config.opts.debugging_opts.mir_opt_level = 0;
+        config.opts.debugging_opts.mir_opt_level = Some(0);
     }
 }
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 2e7b42b6c7c..9a82591e5a7 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1960,7 +1960,7 @@ impl<'test> TestCx<'test> {
                 rustc.args(&[
                     "-Copt-level=1",
                     "-Zdump-mir=all",
-                    "-Zmir-opt-level=3",
+                    "-Zmir-opt-level=4",
                     "-Zvalidate-mir",
                     "-Zdump-mir-exclude-pass-number",
                 ]);