about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-01 07:38:47 +0000
committerbors <bors@rust-lang.org>2020-10-01 07:38:47 +0000
commitfc42fb8e70af6ad63998f4bfbf62451551eda073 (patch)
tree13a17a2ee45eb37c3e35980dfb9a6cfcaff70ca9
parent00730fd0f1df0718f4e0f82298bff3bf1f44a98b (diff)
parent1301f43119f8ae564a01abd3fa306e87d635e862 (diff)
downloadrust-fc42fb8e70af6ad63998f4bfbf62451551eda073.tar.gz
rust-fc42fb8e70af6ad63998f4bfbf62451551eda073.zip
Auto merge of #77354 - ecstatic-morse:const-checking-moar-errors, r=oli-obk
Overhaul const-checking diagnostics

The primary purpose of this PR was to remove `NonConstOp::STOPS_CONST_CHECKING`, which causes any additional errors found by the const-checker to be silenced. I used this flag to preserve diagnostic parity with `qualify_min_const_fn.rs`, which has since been removed.

However, simply removing the flag caused a deluge of errors in some cases, since an error would be emitted any time a local or temporary had a wrong type. To remedy this, I added an alternative system (`DiagnosticImportance`) to silence additional error messages that were likely to distract the user from the underlying issue. When an error of the highest importance occurs, all less important errors are silenced. When no error of the highest importance occurs, all less important errors are emitted after checking is complete. Following the suggestions from the important error is usually enough to fix the less important errors, so this should lead to better UX most of the time.

There's also some unrelated diagnostics improvements in this PR isolated in their own commits. Splitting them out would be possible, but a bit of a pain. This isn't as tidy as some of my other PRs, but it should *only* affect diagnostics, never whether or not something passes const-checking. Note that there are a few trivial exceptions to this, like banning `Yield` in all const-contexts, not just `const fn`.

As always, meant to be reviewed commit-by-commit.

r? `@oli-obk`
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0019.md36
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/mod.rs10
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs310
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs4
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs127
-rw-r--r--src/test/compile-fail/consts/const-fn-error.rs2
-rw-r--r--src/test/ui/async-await/no-const-async.rs1
-rw-r--r--src/test/ui/async-await/no-const-async.stderr12
-rw-r--r--src/test/ui/check-static-values-constraints.rs7
-rw-r--r--src/test/ui/check-static-values-constraints.stderr76
-rw-r--r--src/test/ui/const-suggest-feature.rs2
-rw-r--r--src/test/ui/const-suggest-feature.stderr13
-rw-r--r--src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs4
-rw-r--r--src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr8
-rw-r--r--src/test/ui/consts/const-eval/mod-static-with-const-fn.rs7
-rw-r--r--src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr16
-rw-r--r--src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs1
-rw-r--r--src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr15
-rw-r--r--src/test/ui/consts/const_let_assign3.rs8
-rw-r--r--src/test/ui/consts/const_let_assign3.stderr14
-rw-r--r--src/test/ui/consts/inline_asm.rs2
-rw-r--r--src/test/ui/consts/inline_asm.stderr4
-rw-r--r--src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr5
-rw-r--r--src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr13
-rw-r--r--src/test/ui/consts/min_const_fn/cast_errors.rs4
-rw-r--r--src/test/ui/consts/min_const_fn/cast_errors.stderr52
-rw-r--r--src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs5
-rw-r--r--src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr19
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.rs21
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr169
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr5
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr5
-rw-r--r--src/test/ui/consts/min_const_fn/mutable_borrow.stderr8
-rw-r--r--src/test/ui/consts/projection_qualif.rs1
-rw-r--r--src/test/ui/consts/projection_qualif.stock.stderr14
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref2.rs1
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr13
-rw-r--r--src/test/ui/error-codes/E0010-teach.rs1
-rw-r--r--src/test/ui/error-codes/E0010-teach.stderr15
-rw-r--r--src/test/ui/error-codes/E0010.rs1
-rw-r--r--src/test/ui/error-codes/E0010.stderr13
-rw-r--r--src/test/ui/error-codes/E0017.rs2
-rw-r--r--src/test/ui/error-codes/E0017.stderr14
-rw-r--r--src/test/ui/error-codes/E0388.rs4
-rw-r--r--src/test/ui/error-codes/E0388.stderr14
-rw-r--r--src/test/ui/issues/issue-7364.rs1
-rw-r--r--src/test/ui/issues/issue-7364.stderr12
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.rs3
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr64
-rw-r--r--src/test/ui/static/static-mut-not-constant.rs1
-rw-r--r--src/test/ui/static/static-mut-not-constant.stderr13
-rw-r--r--src/test/ui/unsafe/ranged_ints2_const.stderr8
58 files changed, 589 insertions, 602 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 8b21dacf787..81f65ac8690 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -18,7 +18,6 @@ E0010: include_str!("./error_codes/E0010.md"),
 E0013: include_str!("./error_codes/E0013.md"),
 E0014: include_str!("./error_codes/E0014.md"),
 E0015: include_str!("./error_codes/E0015.md"),
-E0019: include_str!("./error_codes/E0019.md"),
 E0023: include_str!("./error_codes/E0023.md"),
 E0025: include_str!("./error_codes/E0025.md"),
 E0026: include_str!("./error_codes/E0026.md"),
@@ -463,6 +462,7 @@ E0776: include_str!("./error_codes/E0776.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
+//  E0019, merged into E0015
 //  E0035, merged into E0087/E0089
 //  E0036, merged into E0087/E0089
 //  E0068,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0019.md b/compiler/rustc_error_codes/src/error_codes/E0019.md
deleted file mode 100644
index 7832468a539..00000000000
--- a/compiler/rustc_error_codes/src/error_codes/E0019.md
+++ /dev/null
@@ -1,36 +0,0 @@
-A function call isn't allowed in the const's initialization expression
-because the expression's value must be known at compile-time.
-
-Erroneous code example:
-
-```compile_fail,E0019
-#![feature(box_syntax)]
-
-fn main() {
-    struct MyOwned;
-
-    static STATIC11: Box<MyOwned> = box MyOwned; // error!
-}
-```
-
-Remember: you can't use a function call inside a const's initialization
-expression! However, you can totally use it anywhere else:
-
-```
-enum Test {
-    V1
-}
-
-impl Test {
-    fn func(&self) -> i32 {
-        12
-    }
-}
-
-fn main() {
-    const FOO: Test = Test::V1;
-
-    FOO.func(); // here is good
-    let x = FOO.func(); // or even here!
-}
-```
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index f9d84bb852f..fee24f0bae8 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -670,7 +670,7 @@ impl Atom for Local {
 }
 
 /// Classifies locals into categories. See `Body::local_kind`.
-#[derive(PartialEq, Eq, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
 pub enum LocalKind {
     /// User-declared variable binding.
     Var,
diff --git a/compiler/rustc_mir/src/transform/check_consts/mod.rs b/compiler/rustc_mir/src/transform/check_consts/mod.rs
index 8d4efd8ae80..8df134860a5 100644
--- a/compiler/rustc_mir/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/mod.rs
@@ -57,6 +57,16 @@ impl ConstCx<'mir, 'tcx> {
             && self.tcx.features().staged_api
             && is_const_stable_const_fn(self.tcx, self.def_id.to_def_id())
     }
+
+    /// Returns the function signature of the item being const-checked if it is a `fn` or `const fn`.
+    pub fn fn_sig(&self) -> Option<&'tcx hir::FnSig<'tcx>> {
+        // Get this from the HIR map instead of a query to avoid cycle errors.
+        //
+        // FIXME: Is this still an issue?
+        let hir_map = self.tcx.hir();
+        let hir_id = hir_map.local_def_id_to_hir_id(self.def_id);
+        hir_map.fn_sig_by_hir_id(hir_id)
+    }
 }
 
 /// Returns `true` if this `DefId` points to one of the official `panic` lang items.
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index 3b8d8a5aa99..25ed7859d21 100644
--- a/compiler/rustc_mir/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
@@ -1,8 +1,9 @@
 //! Concrete error types for all operations which may be invalid in a certain const context.
 
-use rustc_errors::{struct_span_err, Applicability};
+use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir;
 use rustc_session::config::nightly_options;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
@@ -10,49 +11,6 @@ use rustc_span::{Span, Symbol};
 
 use super::ConstCx;
 
-/// Emits an error and returns `true` if `op` is not allowed in the given const context.
-pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> bool {
-    debug!("illegal_op: op={:?}", op);
-
-    let gate = match op.status_in_item(ccx) {
-        Status::Allowed => return false,
-
-        Status::Unstable(gate) if ccx.tcx.features().enabled(gate) => {
-            let unstable_in_stable = ccx.is_const_stable_const_fn()
-                && !super::allow_internal_unstable(ccx.tcx, ccx.def_id.to_def_id(), gate);
-
-            if unstable_in_stable {
-                ccx.tcx.sess
-                    .struct_span_err(
-                        span,
-                        &format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
-                    )
-                    .span_suggestion(
-                        ccx.body.span,
-                        "if it is not part of the public API, make this function unstably const",
-                        concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
-                        Applicability::HasPlaceholders,
-                    )
-                    .note("otherwise `#[allow_internal_unstable]` can be used to bypass stability checks")
-                    .emit();
-            }
-
-            return unstable_in_stable;
-        }
-
-        Status::Unstable(gate) => Some(gate),
-        Status::Forbidden => None,
-    };
-
-    if ccx.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
-        ccx.tcx.sess.miri_unleashed_feature(span, gate);
-        return false;
-    }
-
-    op.emit_error(ccx, span);
-    true
-}
-
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum Status {
     Allowed,
@@ -60,63 +18,44 @@ pub enum Status {
     Forbidden,
 }
 
+#[derive(Clone, Copy)]
+pub enum DiagnosticImportance {
+    /// An operation that must be removed for const-checking to pass.
+    Primary,
+
+    /// An operation that causes const-checking to fail, but is usually a side-effect of a `Primary` operation elsewhere.
+    Secondary,
+}
+
 /// An operation that is not *always* allowed in a const context.
 pub trait NonConstOp: std::fmt::Debug {
-    const STOPS_CONST_CHECKING: bool = false;
-
     /// Returns an enum indicating whether this operation is allowed within the given item.
     fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
         Status::Forbidden
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        let mut err = struct_span_err!(
-            ccx.tcx.sess,
-            span,
-            E0019,
-            "{} contains unimplemented expression type",
-            ccx.const_kind()
-        );
-
-        if let Status::Unstable(gate) = self.status_in_item(ccx) {
-            if !ccx.tcx.features().enabled(gate) && nightly_options::is_nightly_build() {
-                err.help(&format!("add `#![feature({})]` to the crate attributes to enable", gate));
-            }
-        }
-
-        if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
-            err.note(
-                "A function call isn't allowed in the const's initialization expression \
-                      because the expression's value must be known at compile-time.",
-            );
-            err.note(
-                "Remember: you can't use a function call inside a const's initialization \
-                      expression! However, you can use it anywhere else.",
-            );
-        }
-        err.emit();
+    fn importance(&self) -> DiagnosticImportance {
+        DiagnosticImportance::Primary
     }
+
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
 }
 
 #[derive(Debug)]
 pub struct Abort;
 impl NonConstOp for Abort {
-    const STOPS_CONST_CHECKING: bool = true;
-
     fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
         mcf_status_in_item(ccx)
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        mcf_emit_error(ccx, span, "abort is not stable in const fn")
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        mcf_build_error(ccx, span, "abort is not stable in const fn")
     }
 }
 
 #[derive(Debug)]
 pub struct FloatingPointOp;
 impl NonConstOp for FloatingPointOp {
-    const STOPS_CONST_CHECKING: bool = true;
-
     fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
         if ccx.const_kind() == hir::ConstContext::ConstFn {
             Status::Unstable(sym::const_fn_floating_point_arithmetic)
@@ -125,28 +64,13 @@ impl NonConstOp for FloatingPointOp {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_fn_floating_point_arithmetic,
             span,
             &format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
         )
-        .emit();
-    }
-}
-
-#[derive(Debug)]
-pub struct NonPrimitiveOp;
-impl NonConstOp for NonPrimitiveOp {
-    const STOPS_CONST_CHECKING: bool = true;
-
-    fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
-        mcf_status_in_item(ccx)
-    }
-
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        mcf_emit_error(ccx, span, "only int, `bool` and `char` operations are stable in const fn")
     }
 }
 
@@ -154,10 +78,8 @@ impl NonConstOp for NonPrimitiveOp {
 #[derive(Debug)]
 pub struct FnCallIndirect;
 impl NonConstOp for FnCallIndirect {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        let mut err =
-            ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn");
-        err.emit();
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn")
     }
 }
 
@@ -165,16 +87,15 @@ impl NonConstOp for FnCallIndirect {
 #[derive(Debug)]
 pub struct FnCallNonConst(pub DefId);
 impl NonConstOp for FnCallNonConst {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        let mut err = struct_span_err!(
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        struct_span_err!(
             ccx.tcx.sess,
             span,
             E0015,
             "calls in {}s are limited to constant functions, \
              tuple structs and tuple variants",
             ccx.const_kind(),
-        );
-        err.emit();
+        )
     }
 }
 
@@ -185,7 +106,7 @@ impl NonConstOp for FnCallNonConst {
 pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
 
 impl NonConstOp for FnCallUnstable {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         let FnCallUnstable(def_id, feature) = *self;
 
         let mut err = ccx.tcx.sess.struct_span_err(
@@ -203,15 +124,14 @@ impl NonConstOp for FnCallUnstable {
                 ));
             }
         }
-        err.emit();
+
+        err
     }
 }
 
 #[derive(Debug)]
 pub struct FnPtrCast;
 impl NonConstOp for FnPtrCast {
-    const STOPS_CONST_CHECKING: bool = true;
-
     fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
         if ccx.const_kind() != hir::ConstContext::ConstFn {
             Status::Allowed
@@ -220,37 +140,32 @@ impl NonConstOp for FnPtrCast {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_fn_fn_ptr_basics,
             span,
             &format!("function pointer casts are not allowed in {}s", ccx.const_kind()),
         )
-        .emit()
     }
 }
 
 #[derive(Debug)]
 pub struct Generator;
 impl NonConstOp for Generator {
-    const STOPS_CONST_CHECKING: bool = true;
-
-    fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
-        // FIXME: This means generator-only MIR is only forbidden in const fn. This is for
-        // compatibility with the old code. Such MIR should be forbidden everywhere.
-        mcf_status_in_item(ccx)
+    fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
+        Status::Forbidden
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        mcf_emit_error(ccx, span, "const fn generators are unstable");
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`")
     }
 }
 
 #[derive(Debug)]
 pub struct HeapAllocation;
 impl NonConstOp for HeapAllocation {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         let mut err = struct_span_err!(
             ccx.tcx.sess,
             span,
@@ -267,38 +182,48 @@ impl NonConstOp for HeapAllocation {
                  be done at compile time.",
             );
         }
-        err.emit();
+        err
     }
 }
 
 #[derive(Debug)]
 pub struct InlineAsm;
-impl NonConstOp for InlineAsm {}
+impl NonConstOp for InlineAsm {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        struct_span_err!(
+            ccx.tcx.sess,
+            span,
+            E0015,
+            "inline assembly is not allowed in {}s",
+            ccx.const_kind()
+        )
+    }
+}
 
 #[derive(Debug)]
 pub struct LiveDrop {
     pub dropped_at: Option<Span>,
 }
 impl NonConstOp for LiveDrop {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        let mut diagnostic = struct_span_err!(
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        let mut err = struct_span_err!(
             ccx.tcx.sess,
             span,
             E0493,
             "destructors cannot be evaluated at compile-time"
         );
-        diagnostic.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()));
+        err.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()));
         if let Some(span) = self.dropped_at {
-            diagnostic.span_label(span, "value is dropped here");
+            err.span_label(span, "value is dropped here");
         }
-        diagnostic.emit();
+        err
     }
 }
 
 #[derive(Debug)]
 pub struct CellBorrow;
 impl NonConstOp for CellBorrow {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         struct_span_err!(
             ccx.tcx.sess,
             span,
@@ -306,7 +231,6 @@ impl NonConstOp for CellBorrow {
             "cannot borrow a constant which may contain \
             interior mutability, create a static instead"
         )
-        .emit();
     }
 }
 
@@ -322,7 +246,7 @@ impl NonConstOp for MutBorrow {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn {
             feature_err(
                 &ccx.tcx.sess.parse_sess,
@@ -353,7 +277,7 @@ impl NonConstOp for MutBorrow {
                       static mut or a global UnsafeCell.",
             );
         }
-        err.emit();
+        err
     }
 }
 
@@ -370,14 +294,13 @@ impl NonConstOp for MutAddressOf {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_mut_refs,
             span,
             &format!("`&raw mut` is not allowed in {}s", ccx.const_kind()),
         )
-        .emit();
     }
 }
 
@@ -387,6 +310,20 @@ impl NonConstOp for MutDeref {
     fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
         Status::Unstable(sym::const_mut_refs)
     }
+
+    fn importance(&self) -> DiagnosticImportance {
+        // Usually a side-effect of a `MutBorrow` somewhere.
+        DiagnosticImportance::Secondary
+    }
+
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        feature_err(
+            &ccx.tcx.sess.parse_sess,
+            sym::const_mut_refs,
+            span,
+            &format!("mutation through a reference is not allowed in {}s", ccx.const_kind()),
+        )
+    }
 }
 
 #[derive(Debug)]
@@ -396,21 +333,20 @@ impl NonConstOp for Panic {
         Status::Unstable(sym::const_panic)
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_panic,
             span,
             &format!("panicking in {}s is unstable", ccx.const_kind()),
         )
-        .emit();
     }
 }
 
 #[derive(Debug)]
 pub struct RawPtrComparison;
 impl NonConstOp for RawPtrComparison {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         let mut err = ccx
             .tcx
             .sess
@@ -419,7 +355,7 @@ impl NonConstOp for RawPtrComparison {
             "see issue #53020 <https://github.com/rust-lang/rust/issues/53020> \
             for more information",
         );
-        err.emit();
+        err
     }
 }
 
@@ -430,14 +366,13 @@ impl NonConstOp for RawPtrDeref {
         Status::Unstable(sym::const_raw_ptr_deref)
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_raw_ptr_deref,
             span,
             &format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
         )
-        .emit();
     }
 }
 
@@ -448,14 +383,13 @@ impl NonConstOp for RawPtrToIntCast {
         Status::Unstable(sym::const_raw_ptr_to_usize_cast)
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_raw_ptr_to_usize_cast,
             span,
             &format!("casting pointers to integers in {}s is unstable", ccx.const_kind(),),
         )
-        .emit();
     }
 }
 
@@ -471,7 +405,7 @@ impl NonConstOp for StaticAccess {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         let mut err = struct_span_err!(
             ccx.tcx.sess,
             span,
@@ -489,7 +423,7 @@ impl NonConstOp for StaticAccess {
             );
             err.help("To fix this, the value can be extracted to a `const` and then used.");
         }
-        err.emit();
+        err
     }
 }
 
@@ -497,7 +431,7 @@ impl NonConstOp for StaticAccess {
 #[derive(Debug)]
 pub struct ThreadLocalAccess;
 impl NonConstOp for ThreadLocalAccess {
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         struct_span_err!(
             ccx.tcx.sess,
             span,
@@ -505,15 +439,12 @@ impl NonConstOp for ThreadLocalAccess {
             "thread-local statics cannot be \
             accessed at compile-time"
         )
-        .emit();
     }
 }
 
 #[derive(Debug)]
 pub struct Transmute;
 impl NonConstOp for Transmute {
-    const STOPS_CONST_CHECKING: bool = true;
-
     fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
         if ccx.const_kind() != hir::ConstContext::ConstFn {
             Status::Allowed
@@ -522,15 +453,15 @@ impl NonConstOp for Transmute {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        feature_err(
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        let mut err = feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_fn_transmute,
             span,
             &format!("`transmute` is not allowed in {}s", ccx.const_kind()),
-        )
-        .note("`transmute` is only allowed in constants and statics for now")
-        .emit();
+        );
+        err.note("`transmute` is only allowed in constants and statics for now");
+        err
     }
 }
 
@@ -546,14 +477,13 @@ impl NonConstOp for UnionAccess {
         }
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
             sym::const_fn_union,
             span,
             "unions in const fn are unstable",
         )
-        .emit();
     }
 }
 
@@ -567,12 +497,12 @@ impl NonConstOp for UnsizingCast {
         mcf_status_in_item(ccx)
     }
 
-    fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-        mcf_emit_error(
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        mcf_build_error(
             ccx,
             span,
             "unsizing casts to types besides slices are not allowed in const fn",
-        );
+        )
     }
 }
 
@@ -581,29 +511,42 @@ pub mod ty {
     use super::*;
 
     #[derive(Debug)]
-    pub struct MutRef;
+    pub struct MutRef(pub mir::LocalKind);
     impl NonConstOp for MutRef {
-        const STOPS_CONST_CHECKING: bool = true;
-
         fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
             Status::Unstable(sym::const_mut_refs)
         }
 
-        fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+        fn importance(&self) -> DiagnosticImportance {
+            match self.0 {
+                mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
+                mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
+                    DiagnosticImportance::Primary
+                }
+            }
+        }
+
+        fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
             feature_err(
                 &ccx.tcx.sess.parse_sess,
                 sym::const_mut_refs,
                 span,
                 &format!("mutable references are not allowed in {}s", ccx.const_kind()),
             )
-            .emit()
         }
     }
 
     #[derive(Debug)]
-    pub struct FnPtr;
+    pub struct FnPtr(pub mir::LocalKind);
     impl NonConstOp for FnPtr {
-        const STOPS_CONST_CHECKING: bool = true;
+        fn importance(&self) -> DiagnosticImportance {
+            match self.0 {
+                mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
+                mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
+                    DiagnosticImportance::Primary
+                }
+            }
+        }
 
         fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
             if ccx.const_kind() != hir::ConstContext::ConstFn {
@@ -613,46 +556,50 @@ pub mod ty {
             }
         }
 
-        fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+        fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
             feature_err(
                 &ccx.tcx.sess.parse_sess,
                 sym::const_fn_fn_ptr_basics,
                 span,
                 &format!("function pointers cannot appear in {}s", ccx.const_kind()),
             )
-            .emit()
         }
     }
 
     #[derive(Debug)]
     pub struct ImplTrait;
     impl NonConstOp for ImplTrait {
-        const STOPS_CONST_CHECKING: bool = true;
-
         fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
             mcf_status_in_item(ccx)
         }
 
-        fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-            mcf_emit_error(ccx, span, "`impl Trait` in const fn is unstable");
+        fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+            mcf_build_error(ccx, span, "`impl Trait` in const fn is unstable")
         }
     }
 
     #[derive(Debug)]
-    pub struct TraitBound;
+    pub struct TraitBound(pub mir::LocalKind);
     impl NonConstOp for TraitBound {
-        const STOPS_CONST_CHECKING: bool = true;
+        fn importance(&self) -> DiagnosticImportance {
+            match self.0 {
+                mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
+                mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
+                    DiagnosticImportance::Primary
+                }
+            }
+        }
 
         fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
             mcf_status_in_item(ccx)
         }
 
-        fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
-            mcf_emit_error(
+        fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+            mcf_build_error(
                 ccx,
                 span,
                 "trait bounds other than `Sized` on const fn parameters are unstable",
-            );
+            )
         }
     }
 
@@ -660,20 +607,17 @@ pub mod ty {
     #[derive(Debug)]
     pub struct TraitBoundNotConst;
     impl NonConstOp for TraitBoundNotConst {
-        const STOPS_CONST_CHECKING: bool = true;
-
         fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
             Status::Unstable(sym::const_trait_bound_opt_out)
         }
 
-        fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
+        fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
             feature_err(
                 &ccx.tcx.sess.parse_sess,
                 sym::const_trait_bound_opt_out,
                 span,
                 "`?const Trait` syntax is unstable",
             )
-            .emit()
         }
     }
 }
@@ -686,12 +630,12 @@ fn mcf_status_in_item(ccx: &ConstCx<'_, '_>) -> Status {
     }
 }
 
-fn mcf_emit_error(ccx: &ConstCx<'_, '_>, span: Span, msg: &str) {
-    struct_span_err!(ccx.tcx.sess, span, E0723, "{}", msg)
-        .note(
-            "see issue #57563 <https://github.com/rust-lang/rust/issues/57563> \
+fn mcf_build_error(ccx: &ConstCx<'_, 'tcx>, span: Span, msg: &str) -> DiagnosticBuilder<'tcx> {
+    let mut err = struct_span_err!(ccx.tcx.sess, span, E0723, "{}", msg);
+    err.note(
+        "see issue #57563 <https://github.com/rust-lang/rust/issues/57563> \
              for more information",
-        )
-        .help("add `#![feature(const_fn)]` to the crate attributes to enable")
-        .emit();
+    );
+    err.help("add `#![feature(const_fn)]` to the crate attributes to enable");
+    err
 }
diff --git a/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs
index 0c171bbc464..9b2568d5abb 100644
--- a/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs
@@ -4,7 +4,7 @@ use rustc_middle::mir::{self, BasicBlock, Location};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 
-use super::ops;
+use super::ops::{self, NonConstOp};
 use super::qualifs::{NeedsDrop, Qualif};
 use super::validation::Qualifs;
 use super::ConstCx;
@@ -56,7 +56,7 @@ impl std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
 
 impl CheckLiveDrops<'mir, 'tcx> {
     fn check_live_drop(&self, span: Span) {
-        ops::non_const(self.ccx, ops::LiveDrop { dropped_at: None }, span);
+        ops::LiveDrop { dropped_at: None }.build_error(self.ccx, span).emit();
     }
 }
 
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index ee6adbc7a45..ab63fd03a33 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -1,8 +1,8 @@
 //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
 
-use rustc_errors::struct_span_err;
-use rustc_hir::{self as hir, LangItem};
-use rustc_hir::{def_id::DefId, HirId};
+use rustc_errors::{struct_span_err, Applicability, Diagnostic};
+use rustc_hir::def_id::DefId;
+use rustc_hir::{self as hir, HirId, LangItem};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
@@ -11,13 +11,14 @@ use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{
     self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt, TypeAndMut,
 };
-use rustc_span::{sym, Span};
+use rustc_span::{sym, Span, Symbol};
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
 use rustc_trait_selection::traits::{self, TraitEngine};
 
+use std::mem;
 use std::ops::Deref;
 
-use super::ops::{self, NonConstOp};
+use super::ops::{self, NonConstOp, Status};
 use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop};
 use super::resolver::FlowSensitiveAnalysis;
 use super::{is_lang_panic_fn, ConstCx, Qualif};
@@ -180,7 +181,8 @@ pub struct Validator<'mir, 'tcx> {
     /// The span of the current statement.
     span: Span,
 
-    const_checking_stopped: bool,
+    error_emitted: bool,
+    secondary_errors: Vec<Diagnostic>,
 }
 
 impl Deref for Validator<'mir, 'tcx> {
@@ -197,13 +199,21 @@ impl Validator<'mir, 'tcx> {
             span: ccx.body.span,
             ccx,
             qualifs: Default::default(),
-            const_checking_stopped: false,
+            error_emitted: false,
+            secondary_errors: Vec::new(),
         }
     }
 
     pub fn check_body(&mut self) {
         let ConstCx { tcx, body, def_id, .. } = *self.ccx;
 
+        // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
+        // no need to emit duplicate errors here.
+        if is_async_fn(self.ccx) || body.generator_kind.is_some() {
+            tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
+            return;
+        }
+
         // The local type and predicate checks are not free and only relevant for `const fn`s.
         if self.const_kind() == hir::ConstContext::ConstFn {
             // Prevent const trait methods from being annotated as `stable`.
@@ -223,20 +233,21 @@ impl Validator<'mir, 'tcx> {
 
             self.check_item_predicates();
 
-            for local in &body.local_decls {
-                if local.internal {
+            for (idx, local) in body.local_decls.iter_enumerated() {
+                // Handle the return place below.
+                if idx == RETURN_PLACE || local.internal {
                     continue;
                 }
 
                 self.span = local.source_info.span;
-                self.check_local_or_return_ty(local.ty);
+                self.check_local_or_return_ty(local.ty, idx);
             }
 
             // impl trait is gone in MIR, so check the return type of a const fn by its signature
             // instead of the type of the return place.
             self.span = body.local_decls[RETURN_PLACE].source_info.span;
             let return_ty = tcx.fn_sig(def_id).output();
-            self.check_local_or_return_ty(return_ty.skip_binder());
+            self.check_local_or_return_ty(return_ty.skip_binder(), RETURN_PLACE);
         }
 
         self.visit_body(&body);
@@ -250,6 +261,17 @@ impl Validator<'mir, 'tcx> {
             let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
             check_return_ty_is_sync(tcx, &body, hir_id);
         }
+
+        // If we got through const-checking without emitting any "primary" errors, emit any
+        // "secondary" errors if they occurred.
+        let secondary_errors = mem::take(&mut self.secondary_errors);
+        if !self.error_emitted {
+            for error in secondary_errors {
+                self.tcx.sess.diagnostic().emit_diagnostic(&error);
+            }
+        } else {
+            assert!(self.tcx.sess.has_errors());
+        }
     }
 
     pub fn qualifs_in_return_place(&mut self) -> ConstQualifs {
@@ -264,15 +286,38 @@ impl Validator<'mir, 'tcx> {
     /// Emits an error at the given `span` if an expression cannot be evaluated in the current
     /// context.
     pub fn check_op_spanned<O: NonConstOp>(&mut self, op: O, span: Span) {
-        // HACK: This is for strict equivalence with the old `qualify_min_const_fn` pass, which
-        // only emitted one error per function. It should be removed and the test output updated.
-        if self.const_checking_stopped {
+        let gate = match op.status_in_item(self.ccx) {
+            Status::Allowed => return,
+
+            Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
+                let unstable_in_stable = self.ccx.is_const_stable_const_fn()
+                    && !super::allow_internal_unstable(self.tcx, self.def_id.to_def_id(), gate);
+                if unstable_in_stable {
+                    emit_unstable_in_stable_error(self.ccx, span, gate);
+                }
+
+                return;
+            }
+
+            Status::Unstable(gate) => Some(gate),
+            Status::Forbidden => None,
+        };
+
+        if self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
+            self.tcx.sess.miri_unleashed_feature(span, gate);
             return;
         }
 
-        let err_emitted = ops::non_const(self.ccx, op, span);
-        if err_emitted && O::STOPS_CONST_CHECKING {
-            self.const_checking_stopped = true;
+        let mut err = op.build_error(self.ccx, span);
+        assert!(err.is_error());
+
+        match op.importance() {
+            ops::DiagnosticImportance::Primary => {
+                self.error_emitted = true;
+                err.emit();
+            }
+
+            ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors),
         }
     }
 
@@ -284,7 +329,9 @@ impl Validator<'mir, 'tcx> {
         self.check_op_spanned(ops::StaticAccess, span)
     }
 
-    fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>) {
+    fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>, local: Local) {
+        let kind = self.body.local_kind(local);
+
         for ty in ty.walk() {
             let ty = match ty.unpack() {
                 GenericArgKind::Type(ty) => ty,
@@ -295,20 +342,20 @@ impl Validator<'mir, 'tcx> {
             };
 
             match *ty.kind() {
-                ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef),
+                ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)),
                 ty::Opaque(..) => self.check_op(ops::ty::ImplTrait),
-                ty::FnPtr(..) => self.check_op(ops::ty::FnPtr),
+                ty::FnPtr(..) => self.check_op(ops::ty::FnPtr(kind)),
 
                 ty::Dynamic(preds, _) => {
                     for pred in preds.iter() {
                         match pred.skip_binder() {
                             ty::ExistentialPredicate::AutoTrait(_)
                             | ty::ExistentialPredicate::Projection(_) => {
-                                self.check_op(ops::ty::TraitBound)
+                                self.check_op(ops::ty::TraitBound(kind))
                             }
                             ty::ExistentialPredicate::Trait(trait_ref) => {
                                 if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() {
-                                    self.check_op(ops::ty::TraitBound)
+                                    self.check_op(ops::ty::TraitBound(kind))
                                 }
                             }
                         }
@@ -353,15 +400,19 @@ impl Validator<'mir, 'tcx> {
                                 let def = generics.type_param(p, tcx);
                                 let span = tcx.def_span(def.def_id);
 
+                                // These are part of the function signature, so treat them like
+                                // arguments when determining importance.
+                                let kind = LocalKind::Arg;
+
                                 if constness == hir::Constness::Const {
-                                    self.check_op_spanned(ops::ty::TraitBound, span);
+                                    self.check_op_spanned(ops::ty::TraitBound(kind), span);
                                 } else if !tcx.features().const_fn
                                     || self.ccx.is_const_stable_const_fn()
                                 {
                                     // HACK: We shouldn't need the conditional above, but trait
                                     // bounds on containing impl blocks are wrongly being marked as
                                     // "not-const".
-                                    self.check_op_spanned(ops::ty::TraitBound, span);
+                                    self.check_op_spanned(ops::ty::TraitBound(kind), span);
                                 }
                             }
                             // other kinds of bounds are either tautologies
@@ -877,3 +928,31 @@ fn place_as_reborrow(
 fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
     ty.is_bool() || ty.is_integral() || ty.is_char()
 }
+
+fn is_async_fn(ccx: &ConstCx<'_, '_>) -> bool {
+    ccx.fn_sig().map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async)
+}
+
+fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
+    let attr_span = ccx.fn_sig().map_or(ccx.body.span, |sig| sig.span.shrink_to_lo());
+
+    ccx.tcx
+        .sess
+        .struct_span_err(
+            span,
+            &format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
+        )
+        .span_suggestion(
+            attr_span,
+            "if it is not part of the public API, make this function unstably const",
+            concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
+            Applicability::HasPlaceholders,
+        )
+        .span_suggestion(
+            attr_span,
+            "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks",
+            format!("#[allow_internal_unstable({})]\n", gate),
+            Applicability::MaybeIncorrect,
+        )
+        .emit();
+}
diff --git a/src/test/compile-fail/consts/const-fn-error.rs b/src/test/compile-fail/consts/const-fn-error.rs
index 64474878603..68a4d414ff3 100644
--- a/src/test/compile-fail/consts/const-fn-error.rs
+++ b/src/test/compile-fail/consts/const-fn-error.rs
@@ -6,6 +6,8 @@ const fn f(x: usize) -> usize {
     let mut sum = 0;
     for i in 0..x {
         //~^ ERROR mutable references
+        //~| ERROR calls in constant functions
+        //~| ERROR calls in constant functions
         //~| ERROR E0080
         //~| ERROR E0744
         sum += i;
diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs
index 57a9f175ca3..b3c59734e03 100644
--- a/src/test/ui/async-await/no-const-async.rs
+++ b/src/test/ui/async-await/no-const-async.rs
@@ -3,4 +3,3 @@
 
 pub const async fn x() {}
 //~^ ERROR functions cannot be both `const` and `async`
-//~| ERROR `impl Trait` in const fn is unstable
diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr
index 4e59bb50767..90ec646c8c0 100644
--- a/src/test/ui/async-await/no-const-async.stderr
+++ b/src/test/ui/async-await/no-const-async.stderr
@@ -7,15 +7,5 @@ LL | pub const async fn x() {}
    |     |     `async` because of this
    |     `const` because of this
 
-error[E0723]: `impl Trait` in const fn is unstable
-  --> $DIR/no-const-async.rs:4:24
-   |
-LL | pub const async fn x() {}
-   |                        ^
-   |
-   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/check-static-values-constraints.rs b/src/test/ui/check-static-values-constraints.rs
index acfb3b5e44b..3d1b5a08227 100644
--- a/src/test/ui/check-static-values-constraints.rs
+++ b/src/test/ui/check-static-values-constraints.rs
@@ -78,7 +78,6 @@ struct MyOwned;
 
 static STATIC11: Box<MyOwned> = box MyOwned;
 //~^ ERROR allocations are not allowed in statics
-//~| ERROR static contains unimplemented expression type
 
 static mut STATIC12: UnsafeStruct = UnsafeStruct;
 
@@ -93,16 +92,12 @@ static mut STATIC14: SafeStruct = SafeStruct {
 
 static STATIC15: &'static [Box<MyOwned>] = &[
     box MyOwned, //~ ERROR allocations are not allowed in statics
-    //~| ERROR contains unimplemented expression
     box MyOwned, //~ ERROR allocations are not allowed in statics
-    //~| ERROR contains unimplemented expression
 ];
 
 static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) = (
     &box MyOwned, //~ ERROR allocations are not allowed in statics
-    //~| ERROR contains unimplemented expression
     &box MyOwned, //~ ERROR allocations are not allowed in statics
-    //~| ERROR contains unimplemented expression
 );
 
 static mut STATIC17: SafeEnum = SafeEnum::Variant1;
@@ -110,11 +105,9 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1;
 static STATIC19: Box<isize> =
     box 3;
 //~^ ERROR allocations are not allowed in statics
-    //~| ERROR contains unimplemented expression
 
 pub fn main() {
     let y = { static x: Box<isize> = box 3; x };
     //~^ ERROR allocations are not allowed in statics
     //~| ERROR cannot move out of static item
-    //~| ERROR contains unimplemented expression
 }
diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr
index 50c1b5088e7..eb640c88e02 100644
--- a/src/test/ui/check-static-values-constraints.stderr
+++ b/src/test/ui/check-static-values-constraints.stderr
@@ -15,92 +15,44 @@ error[E0010]: allocations are not allowed in statics
 LL | static STATIC11: Box<MyOwned> = box MyOwned;
    |                                 ^^^^^^^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:79:37
-   |
-LL | static STATIC11: Box<MyOwned> = box MyOwned;
-   |                                     ^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/check-static-values-constraints.rs:90:32
+  --> $DIR/check-static-values-constraints.rs:89:32
    |
 LL |     field2: SafeEnum::Variant4("str".to_string())
    |                                ^^^^^^^^^^^^^^^^^
 
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:95:5
+  --> $DIR/check-static-values-constraints.rs:94:5
    |
 LL |     box MyOwned,
    |     ^^^^^^^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:95:9
-   |
-LL |     box MyOwned,
-   |         ^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:97:5
+  --> $DIR/check-static-values-constraints.rs:95:5
    |
 LL |     box MyOwned,
    |     ^^^^^^^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:97:9
-   |
-LL |     box MyOwned,
-   |         ^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:102:6
+  --> $DIR/check-static-values-constraints.rs:99:6
    |
 LL |     &box MyOwned,
    |      ^^^^^^^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:102:10
-   |
-LL |     &box MyOwned,
-   |          ^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:104:6
+  --> $DIR/check-static-values-constraints.rs:100:6
    |
 LL |     &box MyOwned,
    |      ^^^^^^^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:104:10
-   |
-LL |     &box MyOwned,
-   |          ^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:111:5
+  --> $DIR/check-static-values-constraints.rs:106:5
    |
 LL |     box 3;
    |     ^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:111:9
-   |
-LL |     box 3;
-   |         ^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0507]: cannot move out of static item `x`
-  --> $DIR/check-static-values-constraints.rs:116:45
+  --> $DIR/check-static-values-constraints.rs:110:45
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                             ^
@@ -109,20 +61,12 @@ LL |     let y = { static x: Box<isize> = box 3; x };
    |                                             help: consider borrowing here: `&x`
 
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:116:38
+  --> $DIR/check-static-values-constraints.rs:110:38
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                      ^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/check-static-values-constraints.rs:116:42
-   |
-LL |     let y = { static x: Box<isize> = box 3; x };
-   |                                          ^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 17 previous errors
+error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0010, E0015, E0019, E0493, E0507.
+Some errors have detailed explanations: E0010, E0015, E0493, E0507.
 For more information about an error, try `rustc --explain E0010`.
diff --git a/src/test/ui/const-suggest-feature.rs b/src/test/ui/const-suggest-feature.rs
index 89fafbbe6f0..d11b91edb88 100644
--- a/src/test/ui/const-suggest-feature.rs
+++ b/src/test/ui/const-suggest-feature.rs
@@ -2,8 +2,6 @@ const WRITE: () = unsafe {
     *std::ptr::null_mut() = 0;
     //~^ ERROR dereferencing raw pointers in constants is unstable
     //~| HELP add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
-    //~| ERROR constant contains unimplemented expression type
-    //~| HELP add `#![feature(const_mut_refs)]` to the crate attributes to enable
 };
 
 fn main() {}
diff --git a/src/test/ui/const-suggest-feature.stderr b/src/test/ui/const-suggest-feature.stderr
index 6b91df6b42d..1ccc3d754ff 100644
--- a/src/test/ui/const-suggest-feature.stderr
+++ b/src/test/ui/const-suggest-feature.stderr
@@ -7,15 +7,6 @@ LL |     *std::ptr::null_mut() = 0;
    = note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
    = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
 
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/const-suggest-feature.rs:2:5
-   |
-LL |     *std::ptr::null_mut() = 0;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0019, E0658.
-For more information about an error, try `rustc --explain E0019`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs
index 4d3c714481a..037c6f9f7e6 100644
--- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs
@@ -1,7 +1,7 @@
 // New test for #53818: modifying static memory at compile-time is not allowed.
 // The test should never compile successfully
 
-#![feature(const_raw_ptr_deref)]
+#![feature(const_raw_ptr_deref, const_mut_refs)]
 
 use std::cell::UnsafeCell;
 
@@ -13,7 +13,7 @@ unsafe impl Sync for Foo {}
 static FOO: Foo = Foo(UnsafeCell::new(42));
 
 static BAR: () = unsafe {
-    *FOO.0.get() = 5; //~ ERROR contains unimplemented expression type
+    *FOO.0.get() = 5; //~ ERROR
 };
 
 fn main() {}
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr
index 14dcc074639..296a6bf5421 100644
--- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr
@@ -1,11 +1,9 @@
-error[E0019]: static contains unimplemented expression type
+error[E0080]: could not evaluate static initializer
   --> $DIR/assign-to-static-within-other-static-2.rs:16:5
    |
 LL |     *FOO.0.get() = 5;
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+   |     ^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0019`.
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs
index 32f0062168b..481e0469463 100644
--- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs
+++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs
@@ -12,14 +12,9 @@ unsafe impl Sync for Foo {}
 
 static FOO: Foo = Foo(UnsafeCell::new(42));
 
-fn foo() {}
-
 static BAR: () = unsafe {
     *FOO.0.get() = 5;
-    //~^ contains unimplemented expression
-
-    foo();
-    //~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants
+    //~^ mutation through a reference
 };
 
 fn main() {
diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr
index 44ae1ecf047..38282c0e300 100644
--- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr
+++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr
@@ -1,18 +1,12 @@
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/mod-static-with-const-fn.rs:18:5
+error[E0658]: mutation through a reference is not allowed in statics
+  --> $DIR/mod-static-with-const-fn.rs:16:5
    |
 LL |     *FOO.0.get() = 5;
    |     ^^^^^^^^^^^^^^^^
    |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
-error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/mod-static-with-const-fn.rs:21:5
-   |
-LL |     foo();
-   |     ^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0015, E0019.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
index 8642954a75b..645a957949c 100644
--- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
+++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
@@ -3,6 +3,7 @@
 const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
 const unsafe extern "C" fn closure() -> fn() { || {} }
 //~^ ERROR function pointer
+//~| ERROR function pointer cast
 const unsafe extern fn use_float() { 1.0 + 1.0; }
 //~^ ERROR floating point arithmetic
 const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
index 455a822e2d0..694e2290808 100644
--- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
+++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
@@ -7,8 +7,17 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/const-extern-fn-min-const-fn.rs:4:48
+   |
+LL | const unsafe extern "C" fn closure() -> fn() { || {} }
+   |                                                ^^^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
 error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const-extern-fn-min-const-fn.rs:6:38
+  --> $DIR/const-extern-fn-min-const-fn.rs:7:38
    |
 LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
    |                                      ^^^^^^^^^
@@ -17,7 +26,7 @@ LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
    = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/const-extern-fn-min-const-fn.rs:8:48
+  --> $DIR/const-extern-fn-min-const-fn.rs:9:48
    |
 LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
    |                                                ^^^^^^^^^^^^
@@ -25,6 +34,6 @@ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
    = note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const_let_assign3.rs b/src/test/ui/consts/const_let_assign3.rs
index 9d5ccb880aa..2fd6e060678 100644
--- a/src/test/ui/consts/const_let_assign3.rs
+++ b/src/test/ui/consts/const_let_assign3.rs
@@ -6,23 +6,21 @@ struct S {
 
 impl S {
     const fn foo(&mut self, x: u32) {
-        //~^ ERROR mutable references
+        //~^ ERROR mutable reference
         self.state = x;
     }
 }
 
 const FOO: S = {
     let mut s = S { state: 42 };
-    s.foo(3); //~ ERROR mutable references are not allowed in constants
+    s.foo(3); //~ ERROR mutable reference
     s
 };
 
 type Array = [u32; {
     let mut x = 2;
-    let y = &mut x;
-//~^ ERROR mutable references are not allowed in constants
+    let y = &mut x; //~ ERROR mutable reference
     *y = 42;
-//~^ ERROR constant contains unimplemented expression type
     *y
 }];
 
diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr
index 15badea0037..dc86e178a42 100644
--- a/src/test/ui/consts/const_let_assign3.stderr
+++ b/src/test/ui/consts/const_let_assign3.stderr
@@ -19,15 +19,7 @@ error[E0764]: mutable references are not allowed in constants
 LL |     let y = &mut x;
    |             ^^^^^^ `&mut` is only allowed in `const fn`
 
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/const_let_assign3.rs:24:5
-   |
-LL |     *y = 42;
-   |     ^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0019, E0658, E0764.
-For more information about an error, try `rustc --explain E0019`.
+Some errors have detailed explanations: E0658, E0764.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/inline_asm.rs b/src/test/ui/consts/inline_asm.rs
index c2ab97e54f0..b8b755018e6 100644
--- a/src/test/ui/consts/inline_asm.rs
+++ b/src/test/ui/consts/inline_asm.rs
@@ -1,6 +1,6 @@
 #![feature(llvm_asm)]
 
 const _: () = unsafe { llvm_asm!("nop") };
-//~^ ERROR contains unimplemented expression type
+//~^ ERROR inline assembly
 
 fn main() {}
diff --git a/src/test/ui/consts/inline_asm.stderr b/src/test/ui/consts/inline_asm.stderr
index 0a064c81366..6fb6b69d220 100644
--- a/src/test/ui/consts/inline_asm.stderr
+++ b/src/test/ui/consts/inline_asm.stderr
@@ -1,4 +1,4 @@
-error[E0019]: constant contains unimplemented expression type
+error[E0015]: inline assembly is not allowed in constants
   --> $DIR/inline_asm.rs:3:24
    |
 LL | const _: () = unsafe { llvm_asm!("nop") };
@@ -8,4 +8,4 @@ LL | const _: () = unsafe { llvm_asm!("nop") };
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0019`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr
index 94f6cda2097..a08d57b6043 100644
--- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr
+++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr
@@ -4,11 +4,14 @@ error: const-stable function cannot use `#[feature(const_fn_fn_ptr_basics)]`
 LL | const fn error(_: fn()) {}
    |                ^
    |
-   = note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
 help: if it is not part of the public API, make this function unstably const
    |
 LL | #[rustc_const_unstable(feature = "...", issue = "...")]
    |
+help: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
+   |
+LL | #[allow_internal_unstable(const_fn_fn_ptr_basics)]
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
index 589085871fb..4e1b7bf119c 100644
--- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
+++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
@@ -1,7 +1,6 @@
 const fn foo(a: i32) -> Vec<i32> {
     vec![1, 2, 3]
     //~^ ERROR allocations are not allowed
-    //~| ERROR unimplemented expression type
     //~| ERROR calls in constant functions
 }
 
diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
index 0f16890141f..23697a8e118 100644
--- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
+++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
@@ -6,15 +6,6 @@ LL |     vec![1, 2, 3]
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0019]: constant function contains unimplemented expression type
-  --> $DIR/bad_const_fn_body_ice.rs:2:5
-   |
-LL |     vec![1, 2, 3]
-   |     ^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
   --> $DIR/bad_const_fn_body_ice.rs:2:5
    |
@@ -23,7 +14,7 @@ LL |     vec![1, 2, 3]
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0010, E0015, E0019.
+Some errors have detailed explanations: E0010, E0015.
 For more information about an error, try `rustc --explain E0010`.
diff --git a/src/test/ui/consts/min_const_fn/cast_errors.rs b/src/test/ui/consts/min_const_fn/cast_errors.rs
index 43ef8ea12eb..b68f47f5cbc 100644
--- a/src/test/ui/consts/min_const_fn/cast_errors.rs
+++ b/src/test/ui/consts/min_const_fn/cast_errors.rs
@@ -3,11 +3,15 @@ fn main() {}
 const fn unsize(x: &[u8; 3]) -> &[u8] { x }
 const fn closure() -> fn() { || {} }
 //~^ ERROR function pointer
+//~| ERROR function pointer cast
 const fn closure2() {
     (|| {}) as fn();
 //~^ ERROR function pointer
 }
 const fn reify(f: fn()) -> unsafe fn() { f }
 //~^ ERROR function pointer
+//~| ERROR function pointer
+//~| ERROR function pointer cast
 const fn reify2() { main as unsafe fn(); }
 //~^ ERROR function pointer
+//~| ERROR function pointer cast
diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr
index ac77c181afd..fb962bdf906 100644
--- a/src/test/ui/consts/min_const_fn/cast_errors.stderr
+++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr
@@ -7,33 +7,69 @@ LL | const fn closure() -> fn() { || {} }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
-error[E0658]: function pointers cannot appear in constant functions
-  --> $DIR/cast_errors.rs:7:5
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/cast_errors.rs:4:30
+   |
+LL | const fn closure() -> fn() { || {} }
+   |                              ^^^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/cast_errors.rs:8:5
    |
 LL |     (|| {}) as fn();
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
 error[E0658]: function pointers cannot appear in constant functions
-  --> $DIR/cast_errors.rs:10:28
+  --> $DIR/cast_errors.rs:11:16
    |
 LL | const fn reify(f: fn()) -> unsafe fn() { f }
-   |                            ^^^^^^^^^^^
+   |                ^
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
 error[E0658]: function pointers cannot appear in constant functions
-  --> $DIR/cast_errors.rs:12:21
+  --> $DIR/cast_errors.rs:11:28
+   |
+LL | const fn reify(f: fn()) -> unsafe fn() { f }
+   |                            ^^^^^^^^^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/cast_errors.rs:11:42
+   |
+LL | const fn reify(f: fn()) -> unsafe fn() { f }
+   |                                          ^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/cast_errors.rs:15:21
+   |
+LL | const fn reify2() { main as unsafe fn(); }
+   |                     ^^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/cast_errors.rs:15:21
    |
 LL | const fn reify2() { main as unsafe fn(); }
-   |                     ^^^^^^^^^^^^^^^^^^^
+   |                     ^^^^
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
-error: aborting due to 4 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs
index 4aaf7b86e45..638ff1d8b9c 100644
--- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs
+++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs
@@ -1,5 +1,8 @@
-const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointer
+const fn cmp(x: fn(), y: fn()) -> bool {
+    //~^ ERROR function pointer
+    //~| ERROR function pointer
     unsafe { x == y }
+    //~^ ERROR pointers cannot be reliably compared
 }
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
index e913b187fee..04c2febeb97 100644
--- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
+++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
@@ -7,6 +7,23 @@ LL | const fn cmp(x: fn(), y: fn()) -> bool {
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: function pointers cannot appear in constant functions
+  --> $DIR/cmp_fn_pointers.rs:1:23
+   |
+LL | const fn cmp(x: fn(), y: fn()) -> bool {
+   |                       ^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
+error: pointers cannot be reliably compared during const eval.
+  --> $DIR/cmp_fn_pointers.rs:4:14
+   |
+LL |     unsafe { x == y }
+   |              ^^^^^^
+   |
+   = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index 06a44b27106..e46127c36bf 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -38,6 +38,8 @@ impl<T> Foo<T> {
     const fn get(&self) -> &T { &self.0 }
     const fn get_mut(&mut self) -> &mut T { &mut self.0 }
     //~^ mutable references
+    //~| mutable references
+    //~| mutable references
 }
 impl<'a, T> Foo<T> {
     const fn new_lt(t: T) -> Self { Foo(t) }
@@ -45,6 +47,8 @@ impl<'a, T> Foo<T> {
     const fn get_lt(&'a self) -> &T { &self.0 }
     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
     //~^ mutable references
+    //~| mutable references
+    //~| mutable references
 }
 impl<T: Sized> Foo<T> {
     const fn new_s(t: T) -> Self { Foo(t) }
@@ -52,11 +56,15 @@ impl<T: Sized> Foo<T> {
     const fn get_s(&self) -> &T { &self.0 }
     const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
     //~^ mutable references
+    //~| mutable references
+    //~| mutable references
 }
 impl<T: ?Sized> Foo<T> {
     const fn get_sq(&self) -> &T { &self.0 }
     const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
     //~^ mutable references
+    //~| mutable references
+    //~| mutable references
 }
 
 
@@ -117,17 +125,24 @@ impl<T: Sync + Sized> Foo<T> {
 struct AlanTuring<T>(T);
 const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
 //~^ ERROR trait bounds other than `Sized`
-const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
-const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
+//~| ERROR destructor
+const fn no_apit(_x: impl std::fmt::Debug) {}
+//~^ ERROR trait bounds other than `Sized`
+//~| ERROR destructor
+const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
+//~^ ERROR trait bounds other than `Sized`
 const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
 //~^ ERROR trait bounds other than `Sized`
+//~| ERROR unsizing cast
+//~| ERROR unsizing cast
 
 const fn no_unsafe() { unsafe {} }
 
 const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-//~^ ERROR trait bounds other than `Sized`
+//~^ ERROR unsizing cast
 
 const fn no_fn_ptrs(_x: fn()) {}
 //~^ ERROR function pointer
 const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
 //~^ ERROR function pointer
+//~| ERROR function pointer cast
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index 5e6bf7ef890..ee5434b147b 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -7,6 +7,15 @@ LL |     const fn into_inner(self) -> T { self.0 }
    |                         constant functions cannot evaluate destructors
 
 error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:39:22
+   |
+LL |     const fn get_mut(&mut self) -> &mut T { &mut self.0 }
+   |                      ^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
   --> $DIR/min_const_fn.rs:39:36
    |
 LL |     const fn get_mut(&mut self) -> &mut T { &mut self.0 }
@@ -15,8 +24,17 @@ LL |     const fn get_mut(&mut self) -> &mut T { &mut self.0 }
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:39:45
+   |
+LL |     const fn get_mut(&mut self) -> &mut T { &mut self.0 }
+   |                                             ^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/min_const_fn.rs:44:28
+  --> $DIR/min_const_fn.rs:46:28
    |
 LL |     const fn into_inner_lt(self) -> T { self.0 }
    |                            ^^^^                - value is dropped here
@@ -24,7 +42,16 @@ LL |     const fn into_inner_lt(self) -> T { self.0 }
    |                            constant functions cannot evaluate destructors
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/min_const_fn.rs:46:42
+  --> $DIR/min_const_fn.rs:48:25
+   |
+LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
+   |                         ^^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:48:42
    |
 LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
    |                                          ^^^^^^
@@ -32,8 +59,17 @@ LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:48:51
+   |
+LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
+   |                                                   ^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/min_const_fn.rs:51:27
+  --> $DIR/min_const_fn.rs:55:27
    |
 LL |     const fn into_inner_s(self) -> T { self.0 }
    |                           ^^^^                - value is dropped here
@@ -41,7 +77,16 @@ LL |     const fn into_inner_s(self) -> T { self.0 }
    |                           constant functions cannot evaluate destructors
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/min_const_fn.rs:53:38
+  --> $DIR/min_const_fn.rs:57:24
+   |
+LL |     const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
+   |                        ^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:57:38
    |
 LL |     const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
    |                                      ^^^^^^
@@ -50,7 +95,25 @@ LL |     const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/min_const_fn.rs:58:39
+  --> $DIR/min_const_fn.rs:57:47
+   |
+LL |     const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
+   |                                               ^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:64:25
+   |
+LL |     const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
+   |                         ^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:64:39
    |
 LL |     const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
    |                                       ^^^^^^
@@ -58,8 +121,17 @@ LL |     const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:64:48
+   |
+LL |     const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
+   |                                                ^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:76:16
+  --> $DIR/min_const_fn.rs:84:16
    |
 LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
    |                ^
@@ -68,7 +140,7 @@ LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:78:18
+  --> $DIR/min_const_fn.rs:86:18
    |
 LL | const fn foo11_2<T: Send>(t: T) -> T { t }
    |                  ^
@@ -77,7 +149,7 @@ LL | const fn foo11_2<T: Send>(t: T) -> T { t }
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0013]: constant functions cannot refer to statics
-  --> $DIR/min_const_fn.rs:82:27
+  --> $DIR/min_const_fn.rs:90:27
    |
 LL | const fn foo25() -> u32 { BAR }
    |                           ^^^
@@ -85,7 +157,7 @@ LL | const fn foo25() -> u32 { BAR }
    = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0013]: constant functions cannot refer to statics
-  --> $DIR/min_const_fn.rs:83:37
+  --> $DIR/min_const_fn.rs:91:37
    |
 LL | const fn foo26() -> &'static u32 { &BAR }
    |                                     ^^^
@@ -93,7 +165,7 @@ LL | const fn foo26() -> &'static u32 { &BAR }
    = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:84:42
+  --> $DIR/min_const_fn.rs:92:42
    |
 LL | const fn foo30(x: *const u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
@@ -102,7 +174,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:86:63
+  --> $DIR/min_const_fn.rs:94:63
    |
 LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
    |                                                               ^^^^^^^^^^
@@ -111,7 +183,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:88:42
+  --> $DIR/min_const_fn.rs:96:42
    |
 LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
@@ -120,7 +192,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: casting pointers to integers in constant functions is unstable
-  --> $DIR/min_const_fn.rs:90:63
+  --> $DIR/min_const_fn.rs:98:63
    |
 LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
    |                                                               ^^^^^^^^^^
@@ -129,7 +201,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
    = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/min_const_fn.rs:93:14
+  --> $DIR/min_const_fn.rs:101:14
    |
 LL | const fn inc(x: &mut i32) { *x += 1 }
    |              ^
@@ -138,7 +210,7 @@ LL | const fn inc(x: &mut i32) { *x += 1 }
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:102:6
+  --> $DIR/min_const_fn.rs:110:6
    |
 LL | impl<T: std::fmt::Debug> Foo<T> {
    |      ^
@@ -147,7 +219,7 @@ LL | impl<T: std::fmt::Debug> Foo<T> {
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:107:6
+  --> $DIR/min_const_fn.rs:115:6
    |
 LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    |      ^
@@ -156,7 +228,7 @@ LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:112:6
+  --> $DIR/min_const_fn.rs:120:6
    |
 LL | impl<T: Sync + Sized> Foo<T> {
    |      ^
@@ -165,7 +237,7 @@ LL | impl<T: Sync + Sized> Foo<T> {
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:118:34
+  --> $DIR/min_const_fn.rs:126:34
    |
 LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    |                                  ^^^^^^^^^^^^^^^^^^^^
@@ -173,8 +245,16 @@ LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
+error[E0493]: destructors cannot be evaluated at compile-time
+  --> $DIR/min_const_fn.rs:126:19
+   |
+LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
+   |                   ^^                                     - value is dropped here
+   |                   |
+   |                   constant functions cannot evaluate destructors
+
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:120:22
+  --> $DIR/min_const_fn.rs:129:22
    |
 LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    |                      ^^^^^^^^^^^^^^^^^^^^
@@ -182,8 +262,16 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
+error[E0493]: destructors cannot be evaluated at compile-time
+  --> $DIR/min_const_fn.rs:129:18
+   |
+LL | const fn no_apit(_x: impl std::fmt::Debug) {}
+   |                  ^^                         - value is dropped here
+   |                  |
+   |                  constant functions cannot evaluate destructors
+
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:121:23
+  --> $DIR/min_const_fn.rs:132:23
    |
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
    |                       ^^
@@ -192,7 +280,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:122:32
+  --> $DIR/min_const_fn.rs:134:32
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -200,17 +288,35 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:127:41
+error[E0723]: unsizing casts to types besides slices are not allowed in const fn
+  --> $DIR/min_const_fn.rs:134:63
+   |
+LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
+   |                                                               ^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn)]` to the crate attributes to enable
+
+error[E0723]: unsizing casts to types besides slices are not allowed in const fn
+  --> $DIR/min_const_fn.rs:134:63
+   |
+LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
+   |                                                               ^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn)]` to the crate attributes to enable
+
+error[E0723]: unsizing casts to types besides slices are not allowed in const fn
+  --> $DIR/min_const_fn.rs:141:42
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                          ^^^
    |
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0658]: function pointers cannot appear in constant functions
-  --> $DIR/min_const_fn.rs:130:21
+  --> $DIR/min_const_fn.rs:144:21
    |
 LL | const fn no_fn_ptrs(_x: fn()) {}
    |                     ^^
@@ -219,7 +325,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {}
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
 error[E0658]: function pointers cannot appear in constant functions
-  --> $DIR/min_const_fn.rs:132:27
+  --> $DIR/min_const_fn.rs:146:27
    |
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
@@ -227,7 +333,16 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
-error: aborting due to 26 previous errors
+error[E0658]: function pointer casts are not allowed in constant functions
+  --> $DIR/min_const_fn.rs:146:46
+   |
+LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
+   |                                              ^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
+
+error: aborting due to 39 previous errors
 
 Some errors have detailed explanations: E0013, E0493, E0658, E0723.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
index 6ca1e59b3af..4a22ef2dffd 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
@@ -10,6 +10,6 @@ const fn no_inner_dyn_trait2(x: Hide) {
 //~^ ERROR trait bounds other than `Sized`
 }
 const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
-//~^ ERROR trait bounds other than `Sized`
+//~^ ERROR unsizing cast
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
index 17e171c2fc9..1394db591ca 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
@@ -7,7 +7,7 @@ LL |     x.0.field;
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: unsizing casts to types besides slices are not allowed in const fn
   --> $DIR/min_const_fn_dyn.rs:12:66
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr
index 8d60436ea39..8d82674bbf2 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr
@@ -7,7 +7,7 @@ LL |     x.0.field;
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
 
-error[E0658]: function pointers cannot appear in constant functions
+error[E0658]: function pointer casts are not allowed in constant functions
   --> $DIR/min_const_fn_fn_ptr.rs:16:59
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
index fa2260b40d1..de6a9a19269 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
@@ -20,11 +20,14 @@ error: const-stable function cannot use `#[feature(const_fn_floating_point_arith
 LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
    |                          ^^^^^^^^^^^^^
    |
-   = note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
 help: if it is not part of the public API, make this function unstably const
    |
 LL | #[rustc_const_unstable(feature = "...", issue = "...")]
    |
+help: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
+   |
+LL | #[allow_internal_unstable(const_fn_floating_point_arithmetic)]
+   |
 
 error: `foo2_gated` is not yet stable as a const fn
   --> $DIR/min_const_fn_libstd_stability.rs:39:32
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
index 1ca5964ce0f..f258deb12a9 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
@@ -20,11 +20,14 @@ error: const-stable function cannot use `#[feature(const_fn_floating_point_arith
 LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
    |                                 ^^^^^^^^^^^^^
    |
-   = note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
 help: if it is not part of the public API, make this function unstably const
    |
 LL | #[rustc_const_unstable(feature = "...", issue = "...")]
    |
+help: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
+   |
+LL | #[allow_internal_unstable(const_fn_floating_point_arithmetic)]
+   |
 
 error: `foo2_gated` is not yet stable as a const fn
   --> $DIR/min_const_unsafe_fn_libstd_stability.rs:39:48
diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr
index 4e5cdbb18aa..8e95a4c68a2 100644
--- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr
+++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr
@@ -1,17 +1,17 @@
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/mutable_borrow.rs:3:9
+  --> $DIR/mutable_borrow.rs:3:13
    |
 LL |     let b = &mut a;
-   |         ^
+   |             ^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/mutable_borrow.rs:12:13
+  --> $DIR/mutable_borrow.rs:12:17
    |
 LL |         let b = &mut a;
-   |             ^
+   |                 ^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs
index 7db970cf137..5e2584a6e95 100644
--- a/src/test/ui/consts/projection_qualif.rs
+++ b/src/test/ui/consts/projection_qualif.rs
@@ -9,7 +9,6 @@ const FOO: &u32 = {
     {
         let b: *mut u32 = &mut a; //~ ERROR mutable references are not allowed in constants
         unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants
-        //[stock]~^ contains unimplemented expression
     }
     &{a}
 };
diff --git a/src/test/ui/consts/projection_qualif.stock.stderr b/src/test/ui/consts/projection_qualif.stock.stderr
index 212f1228645..fad8f011f75 100644
--- a/src/test/ui/consts/projection_qualif.stock.stderr
+++ b/src/test/ui/consts/projection_qualif.stock.stderr
@@ -13,15 +13,7 @@ LL |         unsafe { *b = 5; }
    = note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
    = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
 
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/projection_qualif.rs:11:18
-   |
-LL |         unsafe { *b = 5; }
-   |                  ^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0019, E0658, E0764.
-For more information about an error, try `rustc --explain E0019`.
+Some errors have detailed explanations: E0658, E0764.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.rs b/src/test/ui/consts/static_mut_containing_mut_ref2.rs
index a6bbe8d6ec2..2821d1a0154 100644
--- a/src/test/ui/consts/static_mut_containing_mut_ref2.rs
+++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs
@@ -6,6 +6,5 @@ static mut STDERR_BUFFER_SPACE: u8 = 0;
 
 pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
 //~^ ERROR  mutable references are not allowed in statics
-//[stock]~| ERROR static contains unimplemented expression type
 
 fn main() {}
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr
index 57fb27e642e..36c280ca5c6 100644
--- a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr
+++ b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr
@@ -4,15 +4,6 @@ error[E0764]: mutable references are not allowed in statics
 LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn`
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/static_mut_containing_mut_ref2.rs:7:45
-   |
-LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0019, E0764.
-For more information about an error, try `rustc --explain E0019`.
+For more information about this error, try `rustc --explain E0764`.
diff --git a/src/test/ui/error-codes/E0010-teach.rs b/src/test/ui/error-codes/E0010-teach.rs
index da51035ab55..fc5dffb37cf 100644
--- a/src/test/ui/error-codes/E0010-teach.rs
+++ b/src/test/ui/error-codes/E0010-teach.rs
@@ -4,6 +4,5 @@
 #![allow(warnings)]
 
 const CON : Box<i32> = box 0; //~ ERROR E0010
-//~^ ERROR constant contains unimplemented expression type
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0010-teach.stderr b/src/test/ui/error-codes/E0010-teach.stderr
index c15ab5c655a..33de9fd685e 100644
--- a/src/test/ui/error-codes/E0010-teach.stderr
+++ b/src/test/ui/error-codes/E0010-teach.stderr
@@ -6,17 +6,6 @@ LL | const CON : Box<i32> = box 0;
    |
    = note: The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
 
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/E0010-teach.rs:6:28
-   |
-LL | const CON : Box<i32> = box 0;
-   |                            ^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-   = note: A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time.
-   = note: Remember: you can't use a function call inside a const's initialization expression! However, you can use it anywhere else.
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0010, E0019.
-For more information about an error, try `rustc --explain E0010`.
+For more information about this error, try `rustc --explain E0010`.
diff --git a/src/test/ui/error-codes/E0010.rs b/src/test/ui/error-codes/E0010.rs
index 3398e2c28ba..e62997640f4 100644
--- a/src/test/ui/error-codes/E0010.rs
+++ b/src/test/ui/error-codes/E0010.rs
@@ -2,6 +2,5 @@
 #![allow(warnings)]
 
 const CON : Box<i32> = box 0; //~ ERROR E0010
-//~^ ERROR constant contains unimplemented expression type
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0010.stderr b/src/test/ui/error-codes/E0010.stderr
index f49fb9c4632..0042333b98a 100644
--- a/src/test/ui/error-codes/E0010.stderr
+++ b/src/test/ui/error-codes/E0010.stderr
@@ -4,15 +4,6 @@ error[E0010]: allocations are not allowed in constants
 LL | const CON : Box<i32> = box 0;
    |                        ^^^^^ allocation not allowed in constants
 
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/E0010.rs:4:28
-   |
-LL | const CON : Box<i32> = box 0;
-   |                            ^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0010, E0019.
-For more information about an error, try `rustc --explain E0010`.
+For more information about this error, try `rustc --explain E0010`.
diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs
index 54d3cc54a84..262f7bc72c7 100644
--- a/src/test/ui/error-codes/E0017.rs
+++ b/src/test/ui/error-codes/E0017.rs
@@ -5,8 +5,8 @@ static mut M: i32 = 3;
 const CR: &'static mut i32 = &mut C; //~ ERROR E0764
                                      //~| WARN taking a mutable
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0764
-                                              //~| ERROR E0019
                                               //~| ERROR cannot borrow
+
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764
                                               //~| WARN taking a mutable
 static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR E0764
diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr
index 40ef6bd97b3..ea591587e6d 100644
--- a/src/test/ui/error-codes/E0017.stderr
+++ b/src/test/ui/error-codes/E0017.stderr
@@ -19,14 +19,6 @@ error[E0764]: mutable references are not allowed in constants
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^ `&mut` is only allowed in `const fn`
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/E0017.rs:7:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0764]: mutable references are not allowed in statics
   --> $DIR/E0017.rs:7:39
    |
@@ -65,7 +57,7 @@ error[E0764]: mutable references are not allowed in statics
 LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
    |                                                    ^^^^^^ `&mut` is only allowed in `const fn`
 
-error: aborting due to 6 previous errors; 2 warnings emitted
+error: aborting due to 5 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0019, E0596, E0764.
-For more information about an error, try `rustc --explain E0019`.
+Some errors have detailed explanations: E0596, E0764.
+For more information about an error, try `rustc --explain E0596`.
diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs
index 8ad586bb30f..bb0c4979b9a 100644
--- a/src/test/ui/error-codes/E0388.rs
+++ b/src/test/ui/error-codes/E0388.rs
@@ -3,9 +3,9 @@ const C: i32 = 2;
 
 const CR: &'static mut i32 = &mut C; //~ ERROR E0764
                                      //~| WARN taking a mutable
-static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0019
-                                              //~| ERROR cannot borrow
+static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow
                                               //~| ERROR E0764
+
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764
                                              //~| WARN taking a mutable
 
diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr
index 39bc717ceec..73e0b139cd0 100644
--- a/src/test/ui/error-codes/E0388.stderr
+++ b/src/test/ui/error-codes/E0388.stderr
@@ -19,14 +19,6 @@ error[E0764]: mutable references are not allowed in constants
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^ `&mut` is only allowed in `const fn`
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/E0388.rs:6:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0764]: mutable references are not allowed in statics
   --> $DIR/E0388.rs:6:39
    |
@@ -59,7 +51,7 @@ error[E0764]: mutable references are not allowed in statics
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^ `&mut` is only allowed in `const fn`
 
-error: aborting due to 5 previous errors; 2 warnings emitted
+error: aborting due to 4 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0019, E0596, E0764.
-For more information about an error, try `rustc --explain E0019`.
+Some errors have detailed explanations: E0596, E0764.
+For more information about an error, try `rustc --explain E0596`.
diff --git a/src/test/ui/issues/issue-7364.rs b/src/test/ui/issues/issue-7364.rs
index 39452897e67..29a1644673d 100644
--- a/src/test/ui/issues/issue-7364.rs
+++ b/src/test/ui/issues/issue-7364.rs
@@ -6,6 +6,5 @@ use std::cell::RefCell;
 static boxed: Box<RefCell<isize>> = box RefCell::new(0);
 //~^ ERROR allocations are not allowed in statics
 //~| ERROR `RefCell<isize>` cannot be shared between threads safely [E0277]
-//~| ERROR static contains unimplemented expression type
 
 fn main() { }
diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr
index 90f3bf53a7b..8ceb3be7ec9 100644
--- a/src/test/ui/issues/issue-7364.stderr
+++ b/src/test/ui/issues/issue-7364.stderr
@@ -4,14 +4,6 @@ error[E0010]: allocations are not allowed in statics
 LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
    |                                     ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/issue-7364.rs:6:41
-   |
-LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
-   |                                         ^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
 error[E0277]: `RefCell<isize>` cannot be shared between threads safely
   --> $DIR/issue-7364.rs:6:1
    |
@@ -23,7 +15,7 @@ LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
    = note: required because it appears within the type `Box<RefCell<isize>>`
    = note: shared static variables must have a type that implements `Sync`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0010, E0019, E0277.
+Some errors have detailed explanations: E0010, E0277.
 For more information about an error, try `rustc --explain E0010`.
diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs
index 6d3fc3ce2f1..c327667f4cd 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.rs
+++ b/src/test/ui/parser/fn-header-semantic-fail.rs
@@ -12,7 +12,6 @@ fn main() {
     extern "C" fn ff4() {} // OK.
     const async unsafe extern "C" fn ff5() {} // OK.
     //~^ ERROR functions cannot be both `const` and `async`
-    //~| ERROR `from_generator` is not yet stable as a const fn
 
     trait X {
         async fn ft1(); //~ ERROR functions in traits cannot be declared `async`
@@ -35,7 +34,6 @@ fn main() {
         const async unsafe extern "C" fn ft5() {}
         //~^ ERROR functions in traits cannot be declared `async`
         //~| ERROR functions in traits cannot be declared const
-        //~| ERROR `from_generator` is not yet stable as a const fn
         //~| ERROR method `ft5` has an incompatible type for trait
         //~| ERROR functions cannot be both `const` and `async`
     }
@@ -47,7 +45,6 @@ fn main() {
         extern "C" fn fi4() {} // OK.
         const async unsafe extern "C" fn fi5() {}
         //~^ ERROR functions cannot be both `const` and `async`
-        //~| ERROR `from_generator` is not yet stable as a const fn
     }
 
     extern {
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
index f1e21884040..4193b3ee695 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -8,7 +8,7 @@ LL |     const async unsafe extern "C" fn ff5() {} // OK.
    |     `const` because of this
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:18:9
+  --> $DIR/fn-header-semantic-fail.rs:17:9
    |
 LL |         async fn ft1();
    |         -----^^^^^^^^^^
@@ -19,19 +19,19 @@ LL |         async fn ft1();
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
 
 error[E0379]: functions in traits cannot be declared const
-  --> $DIR/fn-header-semantic-fail.rs:20:9
+  --> $DIR/fn-header-semantic-fail.rs:19:9
    |
 LL |         const fn ft3();
    |         ^^^^^ functions in traits cannot be const
 
 error[E0379]: functions in traits cannot be declared const
-  --> $DIR/fn-header-semantic-fail.rs:22:9
+  --> $DIR/fn-header-semantic-fail.rs:21:9
    |
 LL |         const async unsafe extern "C" fn ft5();
    |         ^^^^^ functions in traits cannot be const
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:22:9
+  --> $DIR/fn-header-semantic-fail.rs:21:9
    |
 LL |         const async unsafe extern "C" fn ft5();
    |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL |         const async unsafe extern "C" fn ft5();
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:22:9
+  --> $DIR/fn-header-semantic-fail.rs:21:9
    |
 LL |         const async unsafe extern "C" fn ft5();
    |         ^^^^^-^^^^^----------------------------
@@ -51,7 +51,7 @@ LL |         const async unsafe extern "C" fn ft5();
    |         `const` because of this
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:30:9
+  --> $DIR/fn-header-semantic-fail.rs:29:9
    |
 LL |         async fn ft1() {}
    |         -----^^^^^^^^^^^^
@@ -62,19 +62,19 @@ LL |         async fn ft1() {}
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
 
 error[E0379]: functions in traits cannot be declared const
-  --> $DIR/fn-header-semantic-fail.rs:33:9
+  --> $DIR/fn-header-semantic-fail.rs:32:9
    |
 LL |         const fn ft3() {}
    |         ^^^^^ functions in traits cannot be const
 
 error[E0379]: functions in traits cannot be declared const
-  --> $DIR/fn-header-semantic-fail.rs:35:9
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^ functions in traits cannot be const
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:35:9
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL |         const async unsafe extern "C" fn ft5() {}
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:35:9
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^-^^^^^------------------------------
@@ -94,7 +94,7 @@ LL |         const async unsafe extern "C" fn ft5() {}
    |         `const` because of this
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:48:9
+  --> $DIR/fn-header-semantic-fail.rs:46:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^-^^^^^------------------------------
@@ -103,7 +103,7 @@ LL |         const async unsafe extern "C" fn fi5() {}
    |         `const` because of this
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:54:18
+  --> $DIR/fn-header-semantic-fail.rs:51:18
    |
 LL |     extern {
    |     ------ in this `extern` block
@@ -113,7 +113,7 @@ LL |         async fn fe1();
    |         help: remove the qualifiers: `fn`
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:55:19
+  --> $DIR/fn-header-semantic-fail.rs:52:19
    |
 LL |     extern {
    |     ------ in this `extern` block
@@ -124,7 +124,7 @@ LL |         unsafe fn fe2();
    |         help: remove the qualifiers: `fn`
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:56:18
+  --> $DIR/fn-header-semantic-fail.rs:53:18
    |
 LL |     extern {
    |     ------ in this `extern` block
@@ -135,7 +135,7 @@ LL |         const fn fe3();
    |         help: remove the qualifiers: `fn`
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:57:23
+  --> $DIR/fn-header-semantic-fail.rs:54:23
    |
 LL |     extern {
    |     ------ in this `extern` block
@@ -146,7 +146,7 @@ LL |         extern "C" fn fe4();
    |         help: remove the qualifiers: `fn`
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:58:42
+  --> $DIR/fn-header-semantic-fail.rs:55:42
    |
 LL |     extern {
    |     ------ in this `extern` block
@@ -157,7 +157,7 @@ LL |         const async unsafe extern "C" fn fe5();
    |         help: remove the qualifiers: `fn`
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:58:9
+  --> $DIR/fn-header-semantic-fail.rs:55:9
    |
 LL |         const async unsafe extern "C" fn fe5();
    |         ^^^^^-^^^^^----------------------------
@@ -165,16 +165,8 @@ LL |         const async unsafe extern "C" fn fe5();
    |         |     `async` because of this
    |         `const` because of this
 
-error: `from_generator` is not yet stable as a const fn
-  --> $DIR/fn-header-semantic-fail.rs:13:44
-   |
-LL |     const async unsafe extern "C" fn ff5() {} // OK.
-   |                                            ^^
-   |
-   = help: add `#![feature(gen_future)]` to the crate attributes to enable
-
 error[E0053]: method `ft1` has an incompatible type for trait
-  --> $DIR/fn-header-semantic-fail.rs:30:24
+  --> $DIR/fn-header-semantic-fail.rs:29:24
    |
 LL |         async fn ft1();
    |                       - type in trait
@@ -189,7 +181,7 @@ LL |         async fn ft1() {}
               found fn pointer `fn() -> impl Future`
 
 error[E0053]: method `ft5` has an incompatible type for trait
-  --> $DIR/fn-header-semantic-fail.rs:35:48
+  --> $DIR/fn-header-semantic-fail.rs:34:48
    |
 LL |         const async unsafe extern "C" fn ft5();
    |                                               - type in trait
@@ -203,23 +195,7 @@ LL |         const async unsafe extern "C" fn ft5() {}
    = note: expected fn pointer `unsafe extern "C" fn()`
               found fn pointer `unsafe extern "C" fn() -> impl Future`
 
-error: `from_generator` is not yet stable as a const fn
-  --> $DIR/fn-header-semantic-fail.rs:35:48
-   |
-LL |         const async unsafe extern "C" fn ft5() {}
-   |                                                ^^
-   |
-   = help: add `#![feature(gen_future)]` to the crate attributes to enable
-
-error: `from_generator` is not yet stable as a const fn
-  --> $DIR/fn-header-semantic-fail.rs:48:48
-   |
-LL |         const async unsafe extern "C" fn fi5() {}
-   |                                                ^^
-   |
-   = help: add `#![feature(gen_future)]` to the crate attributes to enable
-
-error: aborting due to 23 previous errors
+error: aborting due to 20 previous errors
 
 Some errors have detailed explanations: E0053, E0379, E0706.
 For more information about an error, try `rustc --explain E0053`.
diff --git a/src/test/ui/static/static-mut-not-constant.rs b/src/test/ui/static/static-mut-not-constant.rs
index 84d401c9fa6..2091fffd418 100644
--- a/src/test/ui/static/static-mut-not-constant.rs
+++ b/src/test/ui/static/static-mut-not-constant.rs
@@ -2,6 +2,5 @@
 
 static mut a: Box<isize> = box 3;
 //~^ ERROR allocations are not allowed in statics
-//~| ERROR static contains unimplemented expression type
 
 fn main() {}
diff --git a/src/test/ui/static/static-mut-not-constant.stderr b/src/test/ui/static/static-mut-not-constant.stderr
index a618b49d108..a0fa245156f 100644
--- a/src/test/ui/static/static-mut-not-constant.stderr
+++ b/src/test/ui/static/static-mut-not-constant.stderr
@@ -4,15 +4,6 @@ error[E0010]: allocations are not allowed in statics
 LL | static mut a: Box<isize> = box 3;
    |                            ^^^^^ allocation not allowed in statics
 
-error[E0019]: static contains unimplemented expression type
-  --> $DIR/static-mut-not-constant.rs:3:32
-   |
-LL | static mut a: Box<isize> = box 3;
-   |                                ^
-   |
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0010, E0019.
-For more information about an error, try `rustc --explain E0010`.
+For more information about this error, try `rustc --explain E0010`.
diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr
index 1a6bcd36ee1..5ce4296458e 100644
--- a/src/test/ui/unsafe/ranged_ints2_const.stderr
+++ b/src/test/ui/unsafe/ranged_ints2_const.stderr
@@ -1,17 +1,17 @@
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/ranged_ints2_const.rs:11:9
+  --> $DIR/ranged_ints2_const.rs:11:13
    |
 LL |     let y = &mut x.0;
-   |         ^
+   |             ^^^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/ranged_ints2_const.rs:18:9
+  --> $DIR/ranged_ints2_const.rs:18:22
    |
 LL |     let y = unsafe { &mut x.0 };
-   |         ^
+   |                      ^^^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable