about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl7
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs51
-rw-r--r--library/core/src/intrinsics/mod.rs2
-rw-r--r--library/core/src/ops/function.rs34
-rw-r--r--tests/ui/consts/fn_trait_refs.stderr175
-rw-r--r--tests/ui/consts/unstable-const-fn-in-libcore.stderr32
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr32
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.rs7
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.stderr58
-rw-r--r--tests/ui/traits/const-traits/call.rs2
-rw-r--r--tests/ui/traits/const-traits/call.stderr7
-rw-r--r--tests/ui/traits/const-traits/const-closure-parse-not-item.stderr32
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr33
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.rs5
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.stderr30
-rw-r--r--tests/ui/traits/const-traits/const-closures.rs5
-rw-r--r--tests/ui/traits/const-traits/const-closures.stderr103
-rw-r--r--tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs5
-rw-r--r--tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr12
-rw-r--r--tests/ui/traits/const-traits/ice-112822-expected-type-for-param.rs6
-rw-r--r--tests/ui/traits/const-traits/ice-112822-expected-type-for-param.stderr46
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs8
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr21
-rw-r--r--tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs2
-rw-r--r--tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr10
28 files changed, 146 insertions, 626 deletions
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index c21b16c9f9f..bac4d70103c 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -82,13 +82,6 @@ hir_typeck_cast_unknown_pointer = cannot cast {$to ->
 hir_typeck_const_continue_bad_label =
     `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
 
-hir_typeck_const_select_must_be_const = this argument must be a `const fn`
-    .help = consult the documentation on `const_eval_select` for more information
-
-hir_typeck_const_select_must_be_fn = this argument must be a function item
-    .note = expected a function item, found {$ty}
-    .help = consult the documentation on `const_eval_select` for more information
-
 hir_typeck_continue_labeled_block =
     `continue` pointing to a labeled block
     .label = labeled blocks cannot be `continue`'d
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 7611f8ac3e1..48bb45de53e 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -578,29 +578,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        if let Some(def_id) = def_id
-            && self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
-            && self.tcx.is_intrinsic(def_id, sym::const_eval_select)
-        {
-            let fn_sig = self.resolve_vars_if_possible(fn_sig);
-            for idx in 0..=1 {
-                let arg_ty = fn_sig.inputs()[idx + 1];
-                let span = arg_exprs.get(idx + 1).map_or(call_expr.span, |arg| arg.span);
-                // Check that second and third argument of `const_eval_select` must be `FnDef`, and additionally that
-                // the second argument must be `const fn`. The first argument must be a tuple, but this is already expressed
-                // in the function signature (`F: FnOnce<ARG>`), so I did not bother to add another check here.
-                //
-                // This check is here because there is currently no way to express a trait bound for `FnDef` types only.
-                if let ty::FnDef(def_id, _args) = *arg_ty.kind() {
-                    if idx == 0 && !self.tcx.is_const_fn(def_id) {
-                        self.dcx().emit_err(errors::ConstSelectMustBeConst { span });
-                    }
-                } else {
-                    self.dcx().emit_err(errors::ConstSelectMustBeFn { span, ty: arg_ty });
-                }
-            }
-        }
-
         fn_sig.output()
     }
 
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 3606c778fc4..a8bb6956f10 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -606,24 +606,6 @@ impl Subdiagnostic for RemoveSemiForCoerce {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_const_select_must_be_const)]
-#[help]
-pub(crate) struct ConstSelectMustBeConst {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(hir_typeck_const_select_must_be_fn)]
-#[note]
-#[help]
-pub(crate) struct ConstSelectMustBeFn<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub ty: Ty<'a>,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_typeck_union_pat_multiple_fields)]
 pub(crate) struct UnionPatMultipleFields {
     #[primary_span]
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 982cfa2e42b..be774106abf 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -529,7 +529,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // process any deferred resolutions.
         let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id);
         for deferred_call_resolution in deferred_call_resolutions {
-            deferred_call_resolution.resolve(self);
+            deferred_call_resolution.resolve(&mut FnCtxt::new(
+                self,
+                self.param_env,
+                closure_def_id,
+            ));
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index 176d308de91..d694a092853 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -1,7 +1,8 @@
 use rustc_hir::{self as hir, LangItem};
 use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
 use rustc_infer::traits::{
-    ImplDerivedHostCause, ImplSource, Obligation, ObligationCauseCode, PredicateObligation,
+    ImplDerivedHostCause, ImplSource, Obligation, ObligationCause, ObligationCauseCode,
+    PredicateObligation,
 };
 use rustc_middle::span_bug;
 use rustc_middle::traits::query::NoSolution;
@@ -303,6 +304,9 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>(
 ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
     match selcx.tcx().as_lang_item(obligation.predicate.def_id()) {
         Some(LangItem::Destruct) => evaluate_host_effect_for_destruct_goal(selcx, obligation),
+        Some(LangItem::Fn | LangItem::FnMut | LangItem::FnOnce) => {
+            evaluate_host_effect_for_fn_goal(selcx, obligation)
+        }
         _ => Err(EvaluationFailure::NoSolution),
     }
 }
@@ -398,6 +402,51 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
         .collect())
 }
 
+// NOTE: Keep this in sync with `extract_fn_def_from_const_callable` in the new solver.
+fn evaluate_host_effect_for_fn_goal<'tcx>(
+    selcx: &mut SelectionContext<'_, 'tcx>,
+    obligation: &HostEffectObligation<'tcx>,
+) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
+    let tcx = selcx.tcx();
+    let self_ty = obligation.predicate.self_ty();
+
+    let (def, args) = match *self_ty.kind() {
+        ty::FnDef(def, args) => (def, args),
+
+        // We may support function pointers at some point in the future
+        ty::FnPtr(..) => return Err(EvaluationFailure::NoSolution),
+
+        // Closures could implement `[const] Fn`,
+        // but they don't really need to right now.
+        ty::Closure(..) | ty::CoroutineClosure(_, _) => {
+            return Err(EvaluationFailure::NoSolution);
+        }
+
+        // Everything else needs explicit impls or cannot have an impl
+        _ => return Err(EvaluationFailure::NoSolution),
+    };
+
+    match tcx.constness(def) {
+        hir::Constness::Const => Ok(tcx
+            .const_conditions(def)
+            .instantiate(tcx, args)
+            .into_iter()
+            .map(|(c, span)| {
+                let code = ObligationCauseCode::WhereClause(def, span);
+                let cause =
+                    ObligationCause::new(obligation.cause.span, obligation.cause.body_id, code);
+                Obligation::new(
+                    tcx,
+                    cause,
+                    obligation.param_env,
+                    c.to_host_effect_clause(tcx, obligation.predicate.constness),
+                )
+            })
+            .collect()),
+        hir::Constness::NotConst => Err(EvaluationFailure::NoSolution),
+    }
+}
+
 fn evaluate_host_effect_from_selection_candidate<'tcx>(
     selcx: &mut SelectionContext<'_, 'tcx>,
     obligation: &HostEffectObligation<'tcx>,
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index f5dcfeebed8..c2e4b751c65 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2279,7 +2279,7 @@ pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
 ) -> RET
 where
     G: FnOnce<ARG, Output = RET>,
-    F: FnOnce<ARG, Output = RET>;
+    F: const FnOnce<ARG, Output = RET>;
 
 /// A macro to make it easier to invoke const_eval_select. Use as follows:
 /// ```rust,ignore (just a macro example)
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
index df48c104410..763b60d88e5 100644
--- a/library/core/src/ops/function.rs
+++ b/library/core/src/ops/function.rs
@@ -72,7 +72,8 @@ use crate::marker::Tuple;
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
-// FIXME(const_trait_impl) #[const_trait]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
 pub trait Fn<Args: Tuple>: FnMut<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -159,7 +160,8 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
-// FIXME(const_trait_impl) #[const_trait]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
 pub trait FnMut<Args: Tuple>: FnOnce<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -238,7 +240,8 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
-// FIXME(const_trait_impl) #[const_trait]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
 pub trait FnOnce<Args: Tuple> {
     /// The returned type after the call operator is used.
     #[lang = "fn_once_output"]
@@ -254,9 +257,10 @@ mod impls {
     use crate::marker::Tuple;
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> Fn<A> for &F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
+    impl<A: Tuple, F: ?Sized> const Fn<A> for &F
     where
-        F: Fn<A>,
+        F: ~const Fn<A>,
     {
         extern "rust-call" fn call(&self, args: A) -> F::Output {
             (**self).call(args)
@@ -264,9 +268,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnMut<A> for &F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
+    impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
     where
-        F: Fn<A>,
+        F: ~const Fn<A>,
     {
         extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
             (**self).call(args)
@@ -274,9 +279,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnOnce<A> for &F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
+    impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
     where
-        F: Fn<A>,
+        F: ~const Fn<A>,
     {
         type Output = F::Output;
 
@@ -286,9 +292,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
+    impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
     where
-        F: FnMut<A>,
+        F: ~const FnMut<A>,
     {
         extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
             (*self).call_mut(args)
@@ -296,9 +303,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
+    impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
     where
-        F: FnMut<A>,
+        F: ~const FnMut<A>,
     {
         type Output = F::Output;
         extern "rust-call" fn call_once(self, args: A) -> F::Output {
diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr
index 445dd75f824..bbe0714801c 100644
--- a/tests/ui/consts/fn_trait_refs.stderr
+++ b/tests/ui/consts/fn_trait_refs.stderr
@@ -4,151 +4,6 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls`
 LL | #![feature(const_fn_trait_ref_impls)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:14:8
-   |
-LL |     T: [const] Fn<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:14:8
-   |
-LL |     T: [const] Fn<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:14:8
-   |
-LL |     T: [const] Fn<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:21:8
-   |
-LL |     T: [const] FnMut<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:21:8
-   |
-LL |     T: [const] FnMut<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:21:8
-   |
-LL |     T: [const] FnMut<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:28:8
-   |
-LL |     T: [const] FnOnce<()>,
-   |        ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:28:8
-   |
-LL |     T: [const] FnOnce<()>,
-   |        ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:28:8
-   |
-LL |     T: [const] FnOnce<()>,
-   |        ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:35:8
-   |
-LL |     T: [const] Fn<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:35:8
-   |
-LL |     T: [const] Fn<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:35:8
-   |
-LL |     T: [const] Fn<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:49:8
-   |
-LL |     T: [const] FnMut<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:49:8
-   |
-LL |     T: [const] FnMut<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:49:8
-   |
-LL |     T: [const] FnMut<()> + [const] Destruct,
-   |        ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied
   --> $DIR/fn_trait_refs.rs:71:17
    |
@@ -161,31 +16,7 @@ error[E0277]: the trait bound `(i32, i32): const PartialEq` is not satisfied
 LL |         assert!(test_two == (2, 2));
    |                 ^^^^^^^^^^^^^^^^^^
 
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/fn_trait_refs.rs:16:5
-   |
-LL |     f()
-   |     ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/fn_trait_refs.rs:23:5
-   |
-LL |     f()
-   |     ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/fn_trait_refs.rs:30:5
-   |
-LL |     f()
-   |     ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 21 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0277, E0635.
-For more information about an error, try `rustc --explain E0015`.
+Some errors have detailed explanations: E0277, E0635.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr
index 95e48b7b7c8..16db7791cd8 100644
--- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr
+++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr
@@ -1,30 +1,3 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/unstable-const-fn-in-libcore.rs:19:32
-   |
-LL |     const fn unwrap_or_else<F: [const] FnOnce() -> T>(self, f: F) -> T {
-   |                                ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/unstable-const-fn-in-libcore.rs:19:32
-   |
-LL |     const fn unwrap_or_else<F: [const] FnOnce() -> T>(self, f: F) -> T {
-   |                                ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/unstable-const-fn-in-libcore.rs:24:26
-   |
-LL |             Opt::None => f(),
-   |                          ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
 error[E0493]: destructor of `F` cannot be evaluated at compile-time
   --> $DIR/unstable-const-fn-in-libcore.rs:19:61
    |
@@ -43,7 +16,6 @@ LL |     const fn unwrap_or_else<F: [const] FnOnce() -> T>(self, f: F) -> T {
 LL |     }
    |     - value is dropped here
 
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index e17737d1860..051eb62d9cb 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -1,22 +1,3 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/normalize-tait-in-const.rs:27:35
-   |
-LL | const fn with_positive<F: for<'a> [const] Fn(&'a Alias<'a>) + [const] Destruct>(fun: F) {
-   |                                   ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/normalize-tait-in-const.rs:27:35
-   |
-LL | const fn with_positive<F: for<'a> [const] Fn(&'a Alias<'a>) + [const] Destruct>(fun: F) {
-   |                                   ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error: unconstrained opaque type
   --> $DIR/normalize-tait-in-const.rs:14:26
    |
@@ -44,15 +25,6 @@ note: this item must have a `#[define_opaque(foo::Alias)]` attribute to be able
 LL |     pub const fn filter_positive<'a>() -> &'a Alias<'a> {
    |                  ^^^^^^^^^^^^^^^
 
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/normalize-tait-in-const.rs:28:5
-   |
-LL |     fun(filter_positive());
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0308.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/intrinsics/const-eval-select-bad.rs b/tests/ui/intrinsics/const-eval-select-bad.rs
index 3365d57af7c..f4071251299 100644
--- a/tests/ui/intrinsics/const-eval-select-bad.rs
+++ b/tests/ui/intrinsics/const-eval-select-bad.rs
@@ -5,13 +5,10 @@ use std::intrinsics::const_eval_select;
 
 const fn not_fn_items() {
     const_eval_select((), || {}, || {});
-    //~^ ERROR this argument must be a function item
-    //~| ERROR this argument must be a function item
+    //~^ ERROR const FnOnce()` is not satisfied
     const_eval_select((), 42, 0xDEADBEEF);
     //~^ ERROR expected a `FnOnce()` closure
     //~| ERROR expected a `FnOnce()` closure
-    //~| ERROR this argument must be a function item
-    //~| ERROR this argument must be a function item
 }
 
 const fn foo(n: i32) -> i32 {
@@ -40,7 +37,7 @@ const fn args_ty_mismatch() {
 
 const fn non_const_fn() {
     const_eval_select((1,), bar, bar);
-    //~^ ERROR this argument must be a `const fn`
+    //~^ ERROR the trait bound `fn(i32) -> bool {bar}: const FnOnce(i32)` is not satisfied
 }
 
 fn main() {}
diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr
index bb159bed282..d701f5ea909 100644
--- a/tests/ui/intrinsics/const-eval-select-bad.stderr
+++ b/tests/ui/intrinsics/const-eval-select-bad.stderr
@@ -1,23 +1,16 @@
-error: this argument must be a function item
+error[E0277]: the trait bound `{closure@$DIR/const-eval-select-bad.rs:7:27: 7:29}: const FnOnce()` is not satisfied
   --> $DIR/const-eval-select-bad.rs:7:27
    |
 LL |     const_eval_select((), || {}, || {});
-   |                           ^^^^^
-   |
-   = note: expected a function item, found {closure@$DIR/const-eval-select-bad.rs:7:27: 7:29}
-   = help: consult the documentation on `const_eval_select` for more information
-
-error: this argument must be a function item
-  --> $DIR/const-eval-select-bad.rs:7:34
-   |
-LL |     const_eval_select((), || {}, || {});
-   |                                  ^^^^^
+   |     -----------------     ^^^^^
+   |     |
+   |     required by a bound introduced by this call
    |
-   = note: expected a function item, found {closure@$DIR/const-eval-select-bad.rs:7:34: 7:36}
-   = help: consult the documentation on `const_eval_select` for more information
+note: required by a bound in `const_eval_select`
+  --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
 
 error[E0277]: expected a `FnOnce()` closure, found `{integer}`
-  --> $DIR/const-eval-select-bad.rs:10:27
+  --> $DIR/const-eval-select-bad.rs:9:27
    |
 LL |     const_eval_select((), 42, 0xDEADBEEF);
    |     -----------------     ^^ expected an `FnOnce()` closure, found `{integer}`
@@ -30,7 +23,7 @@ note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
 
 error[E0277]: expected a `FnOnce()` closure, found `{integer}`
-  --> $DIR/const-eval-select-bad.rs:10:31
+  --> $DIR/const-eval-select-bad.rs:9:31
    |
 LL |     const_eval_select((), 42, 0xDEADBEEF);
    |     -----------------         ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}`
@@ -42,26 +35,8 @@ LL |     const_eval_select((), 42, 0xDEADBEEF);
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
 
-error: this argument must be a function item
-  --> $DIR/const-eval-select-bad.rs:10:27
-   |
-LL |     const_eval_select((), 42, 0xDEADBEEF);
-   |                           ^^
-   |
-   = note: expected a function item, found {integer}
-   = help: consult the documentation on `const_eval_select` for more information
-
-error: this argument must be a function item
-  --> $DIR/const-eval-select-bad.rs:10:31
-   |
-LL |     const_eval_select((), 42, 0xDEADBEEF);
-   |                               ^^^^^^^^^^
-   |
-   = note: expected a function item, found {integer}
-   = help: consult the documentation on `const_eval_select` for more information
-
 error[E0271]: expected `bar` to return `i32`, but it returns `bool`
-  --> $DIR/const-eval-select-bad.rs:32:34
+  --> $DIR/const-eval-select-bad.rs:29:34
    |
 LL |     const_eval_select((1,), foo, bar);
    |     -----------------            ^^^ expected `i32`, found `bool`
@@ -72,7 +47,7 @@ note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/const-eval-select-bad.rs:37:32
+  --> $DIR/const-eval-select-bad.rs:34:32
    |
 LL | const fn foo(n: i32) -> i32 {
    | --------------------------- found signature defined here
@@ -91,15 +66,18 @@ help: consider wrapping the function in a closure
 LL |     const_eval_select((true,), |arg0: bool| foo(/* i32 */), baz);
    |                                ++++++++++++    +++++++++++
 
-error: this argument must be a `const fn`
-  --> $DIR/const-eval-select-bad.rs:42:29
+error[E0277]: the trait bound `fn(i32) -> bool {bar}: const FnOnce(i32)` is not satisfied
+  --> $DIR/const-eval-select-bad.rs:39:29
    |
 LL |     const_eval_select((1,), bar, bar);
-   |                             ^^^
+   |     -----------------       ^^^
+   |     |
+   |     required by a bound introduced by this call
    |
-   = help: consult the documentation on `const_eval_select` for more information
+note: required by a bound in `const_eval_select`
+  --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
 
-error: aborting due to 9 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0271, E0277, E0631.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs
index b985e3da345..b1080fe78bb 100644
--- a/tests/ui/traits/const-traits/call.rs
+++ b/tests/ui/traits/const-traits/call.rs
@@ -5,7 +5,7 @@
 
 pub const _: () = {
     assert!((const || true)());
-    //~^ ERROR cannot call non-const closure in constants
+    //~^ ERROR }: [const] Fn()` is not satisfied
 };
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/call.stderr b/tests/ui/traits/const-traits/call.stderr
index e9bf64092f3..8e32cab6dfc 100644
--- a/tests/ui/traits/const-traits/call.stderr
+++ b/tests/ui/traits/const-traits/call.stderr
@@ -1,12 +1,9 @@
-error[E0015]: cannot call non-const closure in constants
+error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] Fn()` is not satisfied
   --> $DIR/call.rs:7:13
    |
 LL |     assert!((const || true)());
    |             ^^^^^^^^^^^^^^^^^
-   |
-   = note: closures need an RFC before allowed to be called in constants
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
index fdfe3b95d55..1d8d5ff1b4f 100644
--- a/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
+++ b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
@@ -1,31 +1,9 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-parse-not-item.rs:7:25
+error[E0277]: the trait bound `{closure@$DIR/const-closure-parse-not-item.rs:8:5: 8:18}: [const] Fn()` is not satisfied
+  --> $DIR/const-closure-parse-not-item.rs:7:20
    |
 LL | const fn test() -> impl [const] Fn() {
-   |                         ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-parse-not-item.rs:7:25
-   |
-LL | const fn test() -> impl [const] Fn() {
-   |                         ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-parse-not-item.rs:7:25
-   |
-LL | const fn test() -> impl [const] Fn() {
-   |                         ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   |                    ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
index 89b202b3438..fddd8d10bcc 100644
--- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
+++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
@@ -1,30 +1,9 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-trait-method-fail.rs:14:32
+error[E0277]: the trait bound `(): const Tr` is not satisfied
+  --> $DIR/const-closure-trait-method-fail.rs:18:23
    |
-LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
-   |                                ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-trait-method-fail.rs:14:32
-   |
-LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
-   |                                ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/const-closure-trait-method-fail.rs:15:5
-   |
-LL |     x(())
-   |     ^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.rs b/tests/ui/traits/const-traits/const-closure-trait-method.rs
index 831d6e27946..6477aa63c68 100644
--- a/tests/ui/traits/const-traits/const-closure-trait-method.rs
+++ b/tests/ui/traits/const-traits/const-closure-trait-method.rs
@@ -1,5 +1,6 @@
-//@ known-bug: #110395
-// FIXME check-pass
+//@ check-pass
+//@ revisions: next old
+//@[next] compile-flags: -Znext-solver
 #![feature(const_trait_impl)]
 
 #[const_trait]
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
deleted file mode 100644
index 6de25dc11ef..00000000000
--- a/tests/ui/traits/const-traits/const-closure-trait-method.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-trait-method.rs:14:32
-   |
-LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
-   |                                ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closure-trait-method.rs:14:32
-   |
-LL | const fn need_const_closure<T: [const] FnOnce(()) -> i32>(x: T) -> i32 {
-   |                                ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/const-closure-trait-method.rs:15:5
-   |
-LL |     x(())
-   |     ^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-closures.rs b/tests/ui/traits/const-traits/const-closures.rs
index 2f6f4dc4ba3..8f1c018ca5d 100644
--- a/tests/ui/traits/const-traits/const-closures.rs
+++ b/tests/ui/traits/const-traits/const-closures.rs
@@ -1,5 +1,6 @@
-//@ known-bug: #110395
-// FIXME check-pass
+//@ check-pass
+//@ revisions: next old
+//@[next] compile-flags: -Znext-solver
 
 #![feature(const_trait_impl)]
 
diff --git a/tests/ui/traits/const-traits/const-closures.stderr b/tests/ui/traits/const-traits/const-closures.stderr
deleted file mode 100644
index 19869b47085..00000000000
--- a/tests/ui/traits/const-traits/const-closures.stderr
+++ /dev/null
@@ -1,103 +0,0 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:8:12
-   |
-LL |         F: [const] FnOnce() -> u8,
-   |            ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:9:12
-   |
-LL |         F: [const] FnMut() -> u8,
-   |            ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:10:12
-   |
-LL |         F: [const] Fn() -> u8,
-   |            ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:8:12
-   |
-LL |         F: [const] FnOnce() -> u8,
-   |            ^^^^^^^ can't be applied to `FnOnce`
-   |
-note: `FnOnce` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:9:12
-   |
-LL |         F: [const] FnMut() -> u8,
-   |            ^^^^^^^ can't be applied to `FnMut`
-   |
-note: `FnMut` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:10:12
-   |
-LL |         F: [const] Fn() -> u8,
-   |            ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:23:20
-   |
-LL | const fn answer<F: [const] Fn() -> u8>(f: &F) -> u8 {
-   |                    ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-closures.rs:23:20
-   |
-LL | const fn answer<F: [const] Fn() -> u8>(f: &F) -> u8 {
-   |                    ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/const-closures.rs:24:5
-   |
-LL |     f() + f()
-   |     ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/const-closures.rs:24:11
-   |
-LL |     f() + f()
-   |           ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/const-closures.rs:12:5
-   |
-LL |     f() * 7
-   |     ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 11 previous errors
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs
index 92427039b43..30002038f68 100644
--- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs
+++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs
@@ -1,3 +1,4 @@
+//@ known-bug: #110395
 //@ compile-flags: -Znext-solver
 #![feature(const_closures, const_trait_impl)]
 #![allow(incomplete_features)]
@@ -11,7 +12,7 @@ impl Foo for () {
 }
 
 fn main() {
-    (const || { (()).foo() })();
-    //~^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions
+    (const || (()).foo())();
+    // ^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions
     // FIXME(const_trait_impl) this should probably say constant closures
 }
diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr
index c08642ba5a3..dab3f14161f 100644
--- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr
+++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr
@@ -1,11 +1,9 @@
-error[E0015]: cannot call non-const method `<() as Foo>::foo` in constant functions
-  --> $DIR/const_closure-const_trait_impl-ice-113381.rs:14:22
+error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice-113381.rs:15:6: 15:14}: [const] Fn()` is not satisfied
+  --> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5
    |
-LL |     (const || { (()).foo() })();
-   |                      ^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL |     (const || (()).foo())();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.rs b/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.rs
index 026f2c0d603..8ee3db445d0 100644
--- a/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.rs
+++ b/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.rs
@@ -1,16 +1,14 @@
 #![feature(const_trait_impl)]
 
 const fn test() -> impl [const] Fn() {
-    //~^ ERROR `[const]` can only be applied to `#[const_trait]` traits
-    //~| ERROR `[const]` can only be applied to `#[const_trait]` traits
-    //~| ERROR `[const]` can only be applied to `#[const_trait]` traits
+    //~^ ERROR: }: [const] Fn()` is not satisfied
     const move || { //~ ERROR const closures are experimental
         let sl: &[u8] = b"foo";
 
         match sl {
             [first, remainder @ ..] => {
                 assert_eq!(first, &b'f');
-                //~^ ERROR cannot call non-const function
+                // FIXME(const_closures) ^ ERROR cannot call non-const function
             }
             [] => panic!(),
         }
diff --git a/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.stderr b/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.stderr
index 78d7b962cc4..abbe0a0070a 100644
--- a/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.stderr
+++ b/tests/ui/traits/const-traits/ice-112822-expected-type-for-param.stderr
@@ -1,5 +1,5 @@
 error[E0658]: const closures are experimental
-  --> $DIR/ice-112822-expected-type-for-param.rs:7:5
+  --> $DIR/ice-112822-expected-type-for-param.rs:5:5
    |
 LL |     const move || {
    |     ^^^^^
@@ -8,45 +8,13 @@ LL |     const move || {
    = help: add `#![feature(const_closures)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/ice-112822-expected-type-for-param.rs:3:25
+error[E0277]: the trait bound `{closure@$DIR/ice-112822-expected-type-for-param.rs:5:5: 5:18}: [const] Fn()` is not satisfied
+  --> $DIR/ice-112822-expected-type-for-param.rs:3:20
    |
 LL | const fn test() -> impl [const] Fn() {
-   |                         ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/ice-112822-expected-type-for-param.rs:3:25
-   |
-LL | const fn test() -> impl [const] Fn() {
-   |                         ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/ice-112822-expected-type-for-param.rs:3:25
-   |
-LL | const fn test() -> impl [const] Fn() {
-   |                         ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0015]: cannot call non-const function `core::panicking::assert_failed::<&u8, &u8>` in constant functions
-  --> $DIR/ice-112822-expected-type-for-param.rs:12:17
-   |
-LL |                 assert_eq!(first, &b'f');
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+   |                    ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0658.
-For more information about an error, try `rustc --explain E0015`.
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
deleted file mode 100644
index f1dbd947161..00000000000
--- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(generic_const_exprs, const_trait_impl)]
-
-const fn with_positive<F: [const] Fn()>() {}
-//~^ ERROR `[const]` can only be applied to `#[const_trait]` traits
-//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
-
-pub fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
deleted file mode 100644
index 1eccb16b46e..00000000000
--- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/ice-123664-unexpected-bound-var.rs:4:27
-   |
-LL | const fn with_positive<F: [const] Fn()>() {}
-   |                           ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-
-error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/ice-123664-unexpected-bound-var.rs:4:27
-   |
-LL | const fn with_positive<F: [const] Fn()>() {}
-   |                           ^^^^^^^ can't be applied to `Fn`
-   |
-note: `Fn` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
index fa0f7869644..d0470fa3458 100644
--- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
+++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
@@ -11,5 +11,5 @@ impl Foo for () {
 
 fn main() {
     (const || { (()).foo() })();
-    //~^ ERROR: cannot call non-const method
+    //~^ ERROR: }: [const] Fn()` is not satisfied
 }
diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
index 2d33406c222..dcf65ab6940 100644
--- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
+++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
@@ -1,11 +1,9 @@
-error[E0015]: cannot call non-const method `<() as Foo>::foo` in constant functions
-  --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:22
+error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] Fn()` is not satisfied
+  --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5
    |
 LL |     (const || { (()).foo() })();
-   |                      ^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.