about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-22 04:22:24 +0000
committerbors <bors@rust-lang.org>2022-09-22 04:22:24 +0000
commit7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e (patch)
tree242508adbaeccdb47f57c20a90717945a433130a
parent626b02a8f97a9e35a647aa18fcdb67cbcb3b09c8 (diff)
parent898c76cd8257ffd91e9de9714215ece477e1065b (diff)
downloadrust-7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e.tar.gz
rust-7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e.zip
Auto merge of #100982 - fee1-dead-contrib:const-impl-requires-const-trait, r=oli-obk
Require `#[const_trait]` on `Trait` for `impl const Trait`

r? `@oli-obk`
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs6
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs44
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs8
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs5
-rw-r--r--compiler/rustc_passes/src/check_const.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs3
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs33
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs6
-rw-r--r--library/alloc/src/boxed.rs3
-rw-r--r--library/core/src/alloc/mod.rs1
-rw-r--r--library/core/src/borrow.rs2
-rw-r--r--library/core/src/cmp.rs36
-rw-r--r--library/core/src/convert/mod.rs6
-rw-r--r--library/core/src/default.rs1
-rw-r--r--library/core/src/iter/traits/collect.rs1
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/ops/arith.rs50
-rw-r--r--library/core/src/ops/bit.rs11
-rw-r--r--library/core/src/ops/deref.rs2
-rw-r--r--library/core/src/ops/drop.rs1
-rw-r--r--library/core/src/ops/function.rs3
-rw-r--r--library/core/src/ops/index.rs2
-rw-r--r--library/core/src/ops/try_trait.rs2
-rw-r--r--library/core/src/slice/index.rs1
-rw-r--r--src/test/ui/const-generics/const_trait_fn-issue-88433.rs1
-rw-r--r--src/test/ui/const-generics/issue-93647.rs2
-rw-r--r--src/test/ui/const-generics/issues/issue-88119.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-98629.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-98629.stderr2
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr4
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr4
-rw-r--r--src/test/ui/consts/const-fn-error.rs6
-rw-r--r--src/test/ui/consts/const-for.rs4
-rw-r--r--src/test/ui/consts/issue-56164.rs6
-rw-r--r--src/test/ui/consts/issue-94675.rs5
-rw-r--r--src/test/ui/consts/issue-94675.stderr33
-rw-r--r--src/test/ui/consts/unstable-const-fn-in-libcore.rs6
-rw-r--r--src/test/ui/consts/unstable-const-fn-in-libcore.stderr29
-rw-r--r--src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr4
-rw-r--r--src/test/ui/issues/issue-25901.rs2
-rw-r--r--src/test/ui/issues/issue-25901.stderr22
-rw-r--r--src/test/ui/issues/issue-50582.stderr4
-rw-r--r--src/test/ui/never_type/issue-52443.rs4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr23
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs9
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr14
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr13
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/nested-closure.rs12
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/static-const-trait-bound.rs18
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs29
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr35
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs18
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr52
-rw-r--r--src/test/ui/stability-attribute/missing-const-stability.rs1
-rw-r--r--src/test/ui/stability-attribute/missing-const-stability.stderr2
80 files changed, 432 insertions, 244 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index c51debdc863..d03f0369648 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -428,12 +428,18 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
             }
 
             if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
+                // const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
+                // this is because the well-formedness of the function does not need to be proved to have `const`
+                // impls for trait bounds.
                 let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
+                let prev = self.cx.param_env;
+                self.cx.param_env = prev.without_const();
                 self.cx.normalize_and_prove_instantiated_predicates(
                     def_id,
                     instantiated_predicates,
                     locations,
                 );
+                self.cx.param_env = prev;
             }
         }
     }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index a8f6507d594..fb35399fa3a 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -13,8 +13,11 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
 use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable};
 use rustc_mir_dataflow::{self, Analysis};
 use rustc_span::{sym, Span, Symbol};
-use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
-use rustc_trait_selection::traits::SelectionContext;
+use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
+use rustc_trait_selection::traits::{
+    self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt,
+};
 
 use std::mem;
 use std::ops::Deref;
@@ -739,6 +742,43 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                         selcx.select(&obligation)
                     });
 
+                    // do a well-formedness check on the trait method being called. This is because typeck only does a
+                    // "non-const" check. This is required for correctness here.
+                    tcx.infer_ctxt().enter(|infcx| {
+                        let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
+                        let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
+                        let hir_id = tcx
+                            .hir()
+                            .local_def_id_to_hir_id(self.body.source.def_id().expect_local());
+                        let cause = || {
+                            ObligationCause::new(
+                                terminator.source_info.span,
+                                hir_id,
+                                ObligationCauseCode::ItemObligation(callee),
+                            )
+                        };
+                        let normalized = infcx.partially_normalize_associated_types_in(
+                            cause(),
+                            param_env,
+                            predicates,
+                        );
+
+                        for p in normalized.obligations {
+                            fulfill_cx.register_predicate_obligation(&infcx, p);
+                        }
+                        for obligation in traits::predicates_for_generics(
+                            |_, _| cause(),
+                            self.param_env,
+                            normalized.value,
+                        ) {
+                            fulfill_cx.register_predicate_obligation(&infcx, obligation);
+                        }
+                        let errors = fulfill_cx.select_all_or_error(&infcx);
+                        if !errors.is_empty() {
+                            infcx.report_fulfillment_errors(&errors, None, false);
+                        }
+                    });
+
                     match implsrc {
                         Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
                             debug!(
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 0f6d7ed9edc..700d9dab64b 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -468,7 +468,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // RFC 2632
     gated!(
         const_trait, Normal, template!(Word), WarnFollowing, const_trait_impl,
-        "`const` is a temporary placeholder for marking a trait that is suitable for `const` \
+        "`const_trait` is a temporary placeholder for marking a trait that is suitable for `const` \
         `impls` and all default bodies as `const`, which may be removed or renamed in the \
         future."
     ),
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 4df4de21a0f..da3b45a4d6b 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -67,6 +67,14 @@ impl<'tcx> PredicateObligation<'tcx> {
             recursion_depth: self.recursion_depth,
         })
     }
+
+    pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
+        self.param_env = self.param_env.without_const();
+        if let ty::PredicateKind::Trait(trait_pred) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
+            self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Trait(trait_pred.without_const())));
+        }
+        self
+    }
 }
 
 impl<'tcx> TraitObligation<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ac4cad8e5d2..982aacc7686 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -861,6 +861,11 @@ impl<'tcx> TraitPredicate<'tcx> {
             (BoundConstness::ConstIfConst, hir::Constness::NotConst) => false,
         }
     }
+
+    pub fn without_const(mut self) -> Self {
+        self.constness = BoundConstness::NotConst;
+        self
+    }
 }
 
 impl<'tcx> PolyTraitPredicate<'tcx> {
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 70518284cf9..4062862ad74 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -192,6 +192,28 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+        let tcx = self.tcx;
+        if let hir::ItemKind::Impl(hir::Impl {
+            constness: hir::Constness::Const,
+            of_trait: Some(trait_ref),
+            ..
+        }) = item.kind
+        {
+            let def_id = trait_ref.trait_def_id().unwrap();
+            let source_map = tcx.sess.source_map();
+            if !tcx.has_attr(def_id, sym::const_trait) {
+                tcx.sess
+                    .struct_span_err(
+                        source_map.guess_head_span(item.span),
+                        "const `impl`s must be for traits marked with `#[const_trait]`",
+                    )
+                    .span_note(
+                        source_map.guess_head_span(tcx.def_span(def_id)),
+                        "this trait must be annotated with `#[const_trait]`",
+                    )
+                    .emit();
+            }
+        }
         intravisit::walk_item(self, item);
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 104a465a3b5..8da68c225d8 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -129,7 +129,7 @@ pub fn predicates_for_generics<'tcx>(
         move |(idx, (predicate, span))| Obligation {
             cause: cause(idx, span),
             recursion_depth: 0,
-            param_env: param_env,
+            param_env,
             predicate,
         },
     )
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 5ea28fb47cf..9722b48a68a 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -392,7 +392,8 @@ impl<'tcx> WfPredicates<'tcx> {
         //     `i32: Clone`
         //     `i32: Copy`
         // ]
-        let obligations = self.nominal_obligations(data.item_def_id, data.substs);
+        // Projection types do not require const predicates.
+        let obligations = self.nominal_obligations_without_const(data.item_def_id, data.substs);
         self.out.extend(obligations);
 
         let tcx = self.tcx();
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 23e04ae6a53..4522678802b 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1406,7 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         })
     }
 
-    #[instrument(level = "debug", skip(self, code, span, def_id, substs))]
+    #[instrument(level = "debug", skip(self, code, span, substs))]
     fn add_required_obligations_with_code(
         &self,
         span: Span,
@@ -1414,15 +1414,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         substs: SubstsRef<'tcx>,
         code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
     ) {
+        let param_env = self.param_env;
+
+        let remap = match self.tcx.def_kind(def_id) {
+            // Associated consts have `Self: ~const Trait` bounds that should be satisfiable when
+            // `Self: Trait` is satisfied because it does not matter whether the impl is `const`.
+            // Therefore we have to remap the param env here to be non-const.
+            hir::def::DefKind::AssocConst => true,
+            hir::def::DefKind::AssocFn
+                if self.tcx.def_kind(self.tcx.parent(def_id)) == hir::def::DefKind::Trait =>
+            {
+                // N.B.: All callsites to this function involve checking a path expression.
+                //
+                // When instantiating a trait method as a function item, it does not actually matter whether
+                // the trait is `const` or not, or whether `where T: ~const Tr` needs to be satisfied as
+                // `const`. If we were to introduce instantiating trait methods as `const fn`s, we would
+                // check that after this, either via a bound `where F: ~const FnOnce` or when coercing to a
+                // `const fn` pointer.
+                //
+                // FIXME(fee1-dead) FIXME(const_trait_impl): update this doc when trait methods can satisfy
+                // `~const FnOnce` or can be coerced to `const fn` pointer.
+                true
+            }
+            _ => false,
+        };
         let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
 
-        for obligation in traits::predicates_for_generics(
+        for mut obligation in traits::predicates_for_generics(
             |idx, predicate_span| {
                 traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
             },
-            self.param_env,
+            param_env,
             bounds,
         ) {
+            if remap {
+                obligation = obligation.without_const(self.tcx);
+            }
             self.register_predicate(obligation);
         }
     }
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 618b01fc55f..1a4c888a5a4 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -366,7 +366,7 @@ fn typeck_with_fallback<'tcx>(
 
     let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
         let param_env = tcx.param_env(def_id);
-        let fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
+        let mut fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
             let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
                 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
                 <dyn AstConv<'_>>::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None)
@@ -459,7 +459,11 @@ fn typeck_with_fallback<'tcx>(
 
         // Closure and generator analysis may run after fallback
         // because they don't constrain other type variables.
+        // Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
+        let prev_constness = fcx.param_env.constness();
+        fcx.param_env = fcx.param_env.without_const();
         fcx.closure_analyze(body);
+        fcx.param_env = fcx.param_env.with_constness(prev_constness);
         assert!(fcx.deferred_call_resolutions.borrow().is_empty());
         // Before the generator analysis, temporary scopes shall be marked to provide more
         // precise information on types to be captured.
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 65e323c9e00..0aff1323f97 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -2037,8 +2037,7 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
  *  could have a method to project a Pin<T> from it.
  */
 #[stable(feature = "pin", since = "1.33.0")]
-#[rustc_const_unstable(feature = "const_box", issue = "92521")]
-impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static {}
+impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
 
 #[unstable(feature = "generator_trait", issue = "43122")]
 impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index 94efa76664f..61553157478 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -107,6 +107,7 @@ impl fmt::Display for AllocError {
 ///
 /// [*currently allocated*]: #currently-allocated-memory
 #[unstable(feature = "allocator_api", issue = "32838")]
+#[const_trait]
 pub unsafe trait Allocator {
     /// Attempts to allocate a block of memory.
     ///
diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs
index 8378611eb18..fdd56cb4eaa 100644
--- a/library/core/src/borrow.rs
+++ b/library/core/src/borrow.rs
@@ -154,6 +154,7 @@
 /// [`String`]: ../../std/string/struct.String.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Borrow"]
+#[const_trait]
 pub trait Borrow<Borrowed: ?Sized> {
     /// Immutably borrows from an owned value.
     ///
@@ -184,6 +185,7 @@ pub trait Borrow<Borrowed: ?Sized> {
 /// an underlying type by providing a mutable reference. See [`Borrow<T>`]
 /// for more information on borrowing as another type.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
     /// Mutably borrows from an owned value.
     ///
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index d9f2d3d64d6..50b8264bac7 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -204,20 +204,10 @@ use self::Ordering::*;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "==")]
 #[doc(alias = "!=")]
-#[cfg_attr(
-    bootstrap,
-    rustc_on_unimplemented(
-        message = "can't compare `{Self}` with `{Rhs}`",
-        label = "no implementation for `{Self} == {Rhs}`"
-    )
-)]
-#[cfg_attr(
-    not(bootstrap),
-    rustc_on_unimplemented(
-        message = "can't compare `{Self}` with `{Rhs}`",
-        label = "no implementation for `{Self} == {Rhs}`",
-        append_const_msg,
-    )
+#[rustc_on_unimplemented(
+    message = "can't compare `{Self}` with `{Rhs}`",
+    label = "no implementation for `{Self} == {Rhs}`",
+    append_const_msg
 )]
 #[const_trait]
 #[rustc_diagnostic_item = "PartialEq"]
@@ -1076,20 +1066,10 @@ impl const PartialOrd for Ordering {
 #[doc(alias = "<")]
 #[doc(alias = "<=")]
 #[doc(alias = ">=")]
-#[cfg_attr(
-    bootstrap,
-    rustc_on_unimplemented(
-        message = "can't compare `{Self}` with `{Rhs}`",
-        label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
-    )
-)]
-#[cfg_attr(
-    not(bootstrap),
-    rustc_on_unimplemented(
-        message = "can't compare `{Self}` with `{Rhs}`",
-        label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
-        append_const_msg,
-    )
+#[rustc_on_unimplemented(
+    message = "can't compare `{Self}` with `{Rhs}`",
+    label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
+    append_const_msg
 )]
 #[const_trait]
 #[rustc_diagnostic_item = "PartialOrd"]
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 05637c16622..0480704a6d6 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -155,6 +155,7 @@ pub const fn identity<T>(x: T) -> T {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")]
+#[const_trait]
 pub trait AsRef<T: ?Sized> {
     /// Converts this type into a shared reference of the (usually inferred) input type.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -197,6 +198,7 @@ pub trait AsRef<T: ?Sized> {
 /// [`Box<T>`]: ../../std/boxed/struct.Box.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
+#[const_trait]
 pub trait AsMut<T: ?Sized> {
     /// Converts this type into a mutable reference of the (usually inferred) input type.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -273,6 +275,7 @@ pub trait AsMut<T: ?Sized> {
 /// [`Vec`]: ../../std/vec/struct.Vec.html
 #[rustc_diagnostic_item = "Into"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait Into<T>: Sized {
     /// Converts this type into the (usually inferred) input type.
     #[must_use]
@@ -368,6 +371,7 @@ pub trait Into<T>: Sized {
     all(_Self = "&str", T = "std::string::String"),
     note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
 ))]
+#[const_trait]
 pub trait From<T>: Sized {
     /// Converts to this type from the input type.
     #[lang = "from"]
@@ -392,6 +396,7 @@ pub trait From<T>: Sized {
 /// [`Into`], see there for details.
 #[rustc_diagnostic_item = "TryInto"]
 #[stable(feature = "try_from", since = "1.34.0")]
+#[const_trait]
 pub trait TryInto<T>: Sized {
     /// The type returned in the event of a conversion error.
     #[stable(feature = "try_from", since = "1.34.0")]
@@ -468,6 +473,7 @@ pub trait TryInto<T>: Sized {
 /// [`try_from`]: TryFrom::try_from
 #[rustc_diagnostic_item = "TryFrom"]
 #[stable(feature = "try_from", since = "1.34.0")]
+#[const_trait]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
     #[stable(feature = "try_from", since = "1.34.0")]
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index b53cd6074b5..a5b4e965552 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -99,6 +99,7 @@
 /// ```
 #[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Default: Sized {
     /// Returns the "default value" for a type.
     ///
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index 12ca508bed2..e598a54b4f1 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -228,6 +228,7 @@ pub trait FromIterator<A>: Sized {
 #[rustc_diagnostic_item = "IntoIterator"]
 #[rustc_skip_array_during_method_dispatch]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait IntoIterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 2c20850dee2..21775c0a6ab 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -141,6 +141,7 @@
 #![feature(const_str_from_utf8_unchecked_mut)]
 #![feature(const_swap)]
 #![feature(const_trait_impl)]
+#![feature(const_try)]
 #![feature(const_type_id)]
 #![feature(const_type_name)]
 #![feature(const_default_impls)]
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index e367be8c167..75c52d3ecfc 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -65,38 +65,15 @@
 /// ```
 #[lang = "add"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(
-    bootstrap,
-    rustc_on_unimplemented(
-        on(
-            all(_Self = "{integer}", Rhs = "{float}"),
-            message = "cannot add a float to an integer",
-        ),
-        on(
-            all(_Self = "{float}", Rhs = "{integer}"),
-            message = "cannot add an integer to a float",
-        ),
-        message = "cannot add `{Rhs}` to `{Self}`",
-        label = "no implementation for `{Self} + {Rhs}`"
-    )
-)]
-#[cfg_attr(
-    not(bootstrap),
-    rustc_on_unimplemented(
-        on(
-            all(_Self = "{integer}", Rhs = "{float}"),
-            message = "cannot add a float to an integer",
-        ),
-        on(
-            all(_Self = "{float}", Rhs = "{integer}"),
-            message = "cannot add an integer to a float",
-        ),
-        message = "cannot add `{Rhs}` to `{Self}`",
-        label = "no implementation for `{Self} + {Rhs}`",
-        append_const_msg,
-    )
+#[rustc_on_unimplemented(
+    on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
+    on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
+    message = "cannot add `{Rhs}` to `{Self}`",
+    label = "no implementation for `{Self} + {Rhs}`",
+    append_const_msg
 )]
 #[doc(alias = "+")]
+#[const_trait]
 pub trait Add<Rhs = Self> {
     /// The resulting type after applying the `+` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -201,9 +178,11 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented(
     message = "cannot subtract `{Rhs}` from `{Self}`",
-    label = "no implementation for `{Self} - {Rhs}`"
+    label = "no implementation for `{Self} - {Rhs}`",
+    append_const_msg
 )]
 #[doc(alias = "-")]
+#[const_trait]
 pub trait Sub<Rhs = Self> {
     /// The resulting type after applying the `-` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -333,6 +312,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
     label = "no implementation for `{Self} * {Rhs}`"
 )]
 #[doc(alias = "*")]
+#[const_trait]
 pub trait Mul<Rhs = Self> {
     /// The resulting type after applying the `*` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -466,6 +446,7 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
     label = "no implementation for `{Self} / {Rhs}`"
 )]
 #[doc(alias = "/")]
+#[const_trait]
 pub trait Div<Rhs = Self> {
     /// The resulting type after applying the `/` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -568,6 +549,7 @@ div_impl_float! { f32 f64 }
     label = "no implementation for `{Self} % {Rhs}`"
 )]
 #[doc(alias = "%")]
+#[const_trait]
 pub trait Rem<Rhs = Self> {
     /// The resulting type after applying the `%` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -682,6 +664,7 @@ rem_impl_float! { f32 f64 }
 #[lang = "neg"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "-")]
+#[const_trait]
 pub trait Neg {
     /// The resulting type after applying the `-` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -755,6 +738,7 @@ neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
 )]
 #[doc(alias = "+")]
 #[doc(alias = "+=")]
+#[const_trait]
 pub trait AddAssign<Rhs = Self> {
     /// Performs the `+=` operation.
     ///
@@ -822,6 +806,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 )]
 #[doc(alias = "-")]
 #[doc(alias = "-=")]
+#[const_trait]
 pub trait SubAssign<Rhs = Self> {
     /// Performs the `-=` operation.
     ///
@@ -880,6 +865,7 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 )]
 #[doc(alias = "*")]
 #[doc(alias = "*=")]
+#[const_trait]
 pub trait MulAssign<Rhs = Self> {
     /// Performs the `*=` operation.
     ///
@@ -938,6 +924,7 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 )]
 #[doc(alias = "/")]
 #[doc(alias = "/=")]
+#[const_trait]
 pub trait DivAssign<Rhs = Self> {
     /// Performs the `/=` operation.
     ///
@@ -999,6 +986,7 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 )]
 #[doc(alias = "%")]
 #[doc(alias = "%=")]
+#[const_trait]
 pub trait RemAssign<Rhs = Self> {
     /// Performs the `%=` operation.
     ///
diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs
index 7c664226fc2..327009801d1 100644
--- a/library/core/src/ops/bit.rs
+++ b/library/core/src/ops/bit.rs
@@ -31,6 +31,7 @@
 #[lang = "not"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "!")]
+#[const_trait]
 pub trait Not {
     /// The resulting type after applying the `!` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -143,6 +144,7 @@ impl const Not for ! {
     message = "no implementation for `{Self} & {Rhs}`",
     label = "no implementation for `{Self} & {Rhs}`"
 )]
+#[const_trait]
 pub trait BitAnd<Rhs = Self> {
     /// The resulting type after applying the `&` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -244,6 +246,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
     message = "no implementation for `{Self} | {Rhs}`",
     label = "no implementation for `{Self} | {Rhs}`"
 )]
+#[const_trait]
 pub trait BitOr<Rhs = Self> {
     /// The resulting type after applying the `|` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -345,6 +348,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
     message = "no implementation for `{Self} ^ {Rhs}`",
     label = "no implementation for `{Self} ^ {Rhs}`"
 )]
+#[const_trait]
 pub trait BitXor<Rhs = Self> {
     /// The resulting type after applying the `^` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -445,6 +449,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
     message = "no implementation for `{Self} << {Rhs}`",
     label = "no implementation for `{Self} << {Rhs}`"
 )]
+#[const_trait]
 pub trait Shl<Rhs = Self> {
     /// The resulting type after applying the `<<` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -564,6 +569,7 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
     message = "no implementation for `{Self} >> {Rhs}`",
     label = "no implementation for `{Self} >> {Rhs}`"
 )]
+#[const_trait]
 pub trait Shr<Rhs = Self> {
     /// The resulting type after applying the `>>` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -692,6 +698,7 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
     message = "no implementation for `{Self} &= {Rhs}`",
     label = "no implementation for `{Self} &= {Rhs}`"
 )]
+#[const_trait]
 pub trait BitAndAssign<Rhs = Self> {
     /// Performs the `&=` operation.
     ///
@@ -764,6 +771,7 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
     message = "no implementation for `{Self} |= {Rhs}`",
     label = "no implementation for `{Self} |= {Rhs}`"
 )]
+#[const_trait]
 pub trait BitOrAssign<Rhs = Self> {
     /// Performs the `|=` operation.
     ///
@@ -836,6 +844,7 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
     message = "no implementation for `{Self} ^= {Rhs}`",
     label = "no implementation for `{Self} ^= {Rhs}`"
 )]
+#[const_trait]
 pub trait BitXorAssign<Rhs = Self> {
     /// Performs the `^=` operation.
     ///
@@ -906,6 +915,7 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
     message = "no implementation for `{Self} <<= {Rhs}`",
     label = "no implementation for `{Self} <<= {Rhs}`"
 )]
+#[const_trait]
 pub trait ShlAssign<Rhs = Self> {
     /// Performs the `<<=` operation.
     ///
@@ -989,6 +999,7 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
     message = "no implementation for `{Self} >>= {Rhs}`",
     label = "no implementation for `{Self} >>= {Rhs}`"
 )]
+#[const_trait]
 pub trait ShrAssign<Rhs = Self> {
     /// Performs the `>>=` operation.
     ///
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index d68932402a4..4f4c99c4ad9 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -61,6 +61,7 @@
 #[doc(alias = "&*")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Deref"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Deref {
     /// The resulting type after dereferencing.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -169,6 +170,7 @@ impl<T: ?Sized> const Deref for &mut T {
 #[lang = "deref_mut"]
 #[doc(alias = "*")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait DerefMut: Deref {
     /// Mutably dereferences the value.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index de9ddb852df..a2c3d978cc4 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -134,6 +134,7 @@
 /// these types cannot have destructors.
 #[lang = "drop"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait Drop {
     /// Executes the destructor for this type.
     ///
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
index 8fdf22cf6f2..2e0a752c815 100644
--- a/library/core/src/ops/function.rs
+++ b/library/core/src/ops/function.rs
@@ -71,6 +71,7 @@
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Fn<Args>: FnMut<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -158,6 +159,7 @@ pub trait Fn<Args>: FnMut<Args> {
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait FnMut<Args>: FnOnce<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -237,6 +239,7 @@ pub trait FnMut<Args>: FnOnce<Args> {
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait FnOnce<Args> {
     /// The returned type after the call operator is used.
     #[lang = "fn_once_output"]
diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs
index e2e569cb7ea..dd4e3ac1c2f 100644
--- a/library/core/src/ops/index.rs
+++ b/library/core/src/ops/index.rs
@@ -55,6 +55,7 @@
 #[doc(alias = "]")]
 #[doc(alias = "[")]
 #[doc(alias = "[]")]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Index<Idx: ?Sized> {
     /// The returned type after indexing.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -163,6 +164,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
 #[doc(alias = "[")]
 #[doc(alias = "]")]
 #[doc(alias = "[]")]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// Performs the mutable indexing (`container[index]`) operation.
     ///
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
index 10f04134409..dfde0b37acf 100644
--- a/library/core/src/ops/try_trait.rs
+++ b/library/core/src/ops/try_trait.rs
@@ -128,6 +128,7 @@ use crate::ops::ControlFlow;
 )]
 #[doc(alias = "?")]
 #[lang = "Try"]
+#[const_trait]
 pub trait Try: FromResidual {
     /// The type of the value produced by `?` when *not* short-circuiting.
     #[unstable(feature = "try_trait_v2", issue = "84277")]
@@ -384,6 +385,7 @@ pub trait Try: FromResidual {
 ))]
 #[rustc_diagnostic_item = "FromResidual"]
 #[unstable(feature = "try_trait_v2", issue = "84277")]
+#[const_trait]
 pub trait FromResidual<R = <Self as Try>::Residual> {
     /// Constructs the type from a compatible `Residual` type.
     ///
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 3ec6bd93e15..916d0262ded 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -160,6 +160,7 @@ mod private_slice_index {
     message = "the type `{T}` cannot be indexed by `{Self}`",
     label = "slice indices are of type `usize` or ranges of `usize`"
 )]
+#[const_trait]
 pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// The output type returned by methods.
     #[stable(feature = "slice_get_slice", since = "1.28.0")]
diff --git a/src/test/ui/const-generics/const_trait_fn-issue-88433.rs b/src/test/ui/const-generics/const_trait_fn-issue-88433.rs
index 8724fa69825..6e04cfaec31 100644
--- a/src/test/ui/const-generics/const_trait_fn-issue-88433.rs
+++ b/src/test/ui/const-generics/const_trait_fn-issue-88433.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Func<T> {
     type Output;
 
diff --git a/src/test/ui/const-generics/issue-93647.rs b/src/test/ui/const-generics/issue-93647.rs
index c1a6bf6e34d..806540e1775 100644
--- a/src/test/ui/const-generics/issue-93647.rs
+++ b/src/test/ui/const-generics/issue-93647.rs
@@ -1,6 +1,6 @@
 struct X<const N: usize = {
     (||1usize)()
-    //~^ ERROR cannot call
+    //~^ ERROR cannot call non-const closure
 }>;
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-88119.rs b/src/test/ui/const-generics/issues/issue-88119.rs
index 70dfa7f708b..647b0eea86d 100644
--- a/src/test/ui/const-generics/issues/issue-88119.rs
+++ b/src/test/ui/const-generics/issues/issue-88119.rs
@@ -3,6 +3,7 @@
 #![allow(incomplete_features)]
 #![feature(const_trait_impl, generic_const_exprs)]
 
+#[const_trait]
 trait ConstName {
     const NAME_BYTES: &'static [u8];
 }
diff --git a/src/test/ui/const-generics/issues/issue-98629.rs b/src/test/ui/const-generics/issues/issue-98629.rs
index fc8666bbcdb..1d2d3012a6e 100644
--- a/src/test/ui/const-generics/issues/issue-98629.rs
+++ b/src/test/ui/const-generics/issues/issue-98629.rs
@@ -1,5 +1,6 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Trait {
     const N: usize;
 }
diff --git a/src/test/ui/const-generics/issues/issue-98629.stderr b/src/test/ui/const-generics/issues/issue-98629.stderr
index 53570220882..4a248be76a9 100644
--- a/src/test/ui/const-generics/issues/issue-98629.stderr
+++ b/src/test/ui/const-generics/issues/issue-98629.stderr
@@ -1,5 +1,5 @@
 error[E0046]: not all trait items implemented, missing: `N`
-  --> $DIR/issue-98629.rs:7:1
+  --> $DIR/issue-98629.rs:8:1
    |
 LL |     const N: usize;
    |     -------------- `N` from trait
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
index 0e6be6d01ed..c685922c456 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
@@ -4,13 +4,13 @@ error[E0308]: mismatched types
 LL |     = [0; (i8::MAX + 1u8) as usize];
    |                      ^^^ expected `i8`, found `u8`
 
-error[E0277]: cannot add `u8` to `i8`
+error[E0277]: cannot add `u8` to `i8` in const contexts
   --> $DIR/const-eval-overflow-3b.rs:16:20
    |
 LL |     = [0; (i8::MAX + 1u8) as usize];
    |                    ^ no implementation for `i8 + u8`
    |
-   = help: the trait `Add<u8>` is not implemented for `i8`
+   = help: the trait `~const Add<u8>` is not implemented for `i8`
    = help: the following other types implement trait `Add<Rhs>`:
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
index 4fa017e04e9..b396079240a 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
@@ -4,13 +4,13 @@ error[E0308]: mismatched types
 LL |     : [u32; (i8::MAX as i8 + 1u8) as usize]
    |                              ^^^ expected `i8`, found `u8`
 
-error[E0277]: cannot add `u8` to `i8`
+error[E0277]: cannot add `u8` to `i8` in const contexts
   --> $DIR/const-eval-overflow-4b.rs:9:28
    |
 LL |     : [u32; (i8::MAX as i8 + 1u8) as usize]
    |                            ^ no implementation for `i8 + u8`
    |
-   = help: the trait `Add<u8>` is not implemented for `i8`
+   = help: the trait `~const Add<u8>` is not implemented for `i8`
    = help: the following other types implement trait `Add<Rhs>`:
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
diff --git a/src/test/ui/consts/const-fn-error.rs b/src/test/ui/consts/const-fn-error.rs
index abe68c17a0d..50b7ce1f8c0 100644
--- a/src/test/ui/consts/const-fn-error.rs
+++ b/src/test/ui/consts/const-fn-error.rs
@@ -3,10 +3,10 @@ const X : usize = 2;
 const fn f(x: usize) -> usize {
     let mut sum = 0;
     for i in 0..x {
-        //~^ ERROR mutable references
-        //~| ERROR cannot convert
-        //~| ERROR cannot call non-const fn
+        //~^ ERROR cannot convert
         //~| ERROR `for` is not allowed in a `const fn`
+        //~| ERROR mutable references are not allowed in constant functions
+        //~| ERROR cannot call non-const fn
         sum += i;
     }
     sum
diff --git a/src/test/ui/consts/const-for.rs b/src/test/ui/consts/const-for.rs
index 58bcb5f74cc..8db24853558 100644
--- a/src/test/ui/consts/const-for.rs
+++ b/src/test/ui/consts/const-for.rs
@@ -3,8 +3,8 @@
 
 const _: () = {
     for _ in 0..5 {}
-    //~^ error: cannot convert
-    //~| error: cannot call non-const fn
+    //~^ error: cannot call
+    //~| error: cannot convert
 };
 
 fn main() {}
diff --git a/src/test/ui/consts/issue-56164.rs b/src/test/ui/consts/issue-56164.rs
index 094ca377e03..fd02d215480 100644
--- a/src/test/ui/consts/issue-56164.rs
+++ b/src/test/ui/consts/issue-56164.rs
@@ -1,11 +1,11 @@
 const fn foo() { (||{})() }
 //~^ ERROR cannot call non-const closure
-//~| ERROR erroneous constant used [const_err]
-//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+//~| ERROR erroneous constant
+//~| WARN this was previously accepted
 
 const fn bad(input: fn()) {
     input()
-    //~^ ERROR function pointer
+    //~^ ERROR function pointer calls are not allowed
 }
 
 fn main() {
diff --git a/src/test/ui/consts/issue-94675.rs b/src/test/ui/consts/issue-94675.rs
index 0604aab3bcd..ce21ebdb9ac 100644
--- a/src/test/ui/consts/issue-94675.rs
+++ b/src/test/ui/consts/issue-94675.rs
@@ -7,9 +7,8 @@ struct Foo<'a> {
 impl<'a> Foo<'a> {
     const fn spam(&mut self, baz: &mut Vec<u32>) {
         self.bar[0] = baz.len();
-        //~^ ERROR cannot call non-const fn `Vec::<u32>::len` in constant functions
-        //~| ERROR the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
-        //~| ERROR cannot call non-const operator in constant functions
+        //~^ the trait bound `Vec<usize>: ~const Index<_>` is not satisfied
+        //~| the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
     }
 }
 
diff --git a/src/test/ui/consts/issue-94675.stderr b/src/test/ui/consts/issue-94675.stderr
index 6665e42835b..7ae293ffbf8 100644
--- a/src/test/ui/consts/issue-94675.stderr
+++ b/src/test/ui/consts/issue-94675.stderr
@@ -1,10 +1,15 @@
-error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions
-  --> $DIR/issue-94675.rs:9:27
+error[E0277]: the trait bound `Vec<usize>: ~const Index<_>` is not satisfied
+  --> $DIR/issue-94675.rs:9:9
    |
 LL |         self.bar[0] = baz.len();
-   |                           ^^^^^
+   |         ^^^^^^^^^^^ vector indices are of type `usize` or ranges of `usize`
+   |
+   = help: the trait `~const Index<_>` is not implemented for `Vec<usize>`
+note: the trait `Index<_>` is implemented for `Vec<usize>`, but that implementation is not `const`
+  --> $DIR/issue-94675.rs:9:9
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL |         self.bar[0] = baz.len();
+   |         ^^^^^^^^^^^
 
 error[E0277]: the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
   --> $DIR/issue-94675.rs:9:9
@@ -18,21 +23,11 @@ note: the trait `IndexMut<usize>` is implemented for `Vec<usize>`, but that impl
    |
 LL |         self.bar[0] = baz.len();
    |         ^^^^^^^^^^^
-
-error[E0015]: cannot call non-const operator in constant functions
-  --> $DIR/issue-94675.rs:9:9
-   |
-LL |         self.bar[0] = baz.len();
-   |         ^^^^^^^^^^^
-   |
-note: impl defined here, but it is not `const`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
-LL | impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL | impl<'a> Foo<'a> where Vec<usize>: ~const IndexMut<usize> {
+   |                  ++++++++++++++++++++++++++++++++++++++++
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0277.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/consts/unstable-const-fn-in-libcore.rs b/src/test/ui/consts/unstable-const-fn-in-libcore.rs
index 16b36c8d56d..b9e7e1405f9 100644
--- a/src/test/ui/consts/unstable-const-fn-in-libcore.rs
+++ b/src/test/ui/consts/unstable-const-fn-in-libcore.rs
@@ -4,7 +4,7 @@
 // gate was not enabled in libcore.
 
 #![stable(feature = "core", since = "1.6.0")]
-#![feature(staged_api)]
+#![feature(staged_api, const_trait_impl)]
 
 enum Opt<T> {
     Some(T),
@@ -14,12 +14,12 @@ enum Opt<T> {
 impl<T> Opt<T> {
     #[rustc_const_unstable(feature = "foo", issue = "none")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
+    const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
     //~^ ERROR destructors cannot be evaluated at compile-time
     //~| ERROR destructors cannot be evaluated at compile-time
         match self {
             Opt::Some(t) => t,
-            Opt::None => f(), //~ ERROR E0015
+            Opt::None => f(),
         }
     }
 }
diff --git a/src/test/ui/consts/unstable-const-fn-in-libcore.stderr b/src/test/ui/consts/unstable-const-fn-in-libcore.stderr
index 180f9f10cc6..fee74bd0a6c 100644
--- a/src/test/ui/consts/unstable-const-fn-in-libcore.stderr
+++ b/src/test/ui/consts/unstable-const-fn-in-libcore.stderr
@@ -1,34 +1,21 @@
-error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/unstable-const-fn-in-libcore.rs:22:26
-   |
-LL |             Opt::None => f(),
-   |                          ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-help: consider further restricting this bound
-   |
-LL |     const fn unwrap_or_else<F: FnOnce() -> T + ~const std::ops::FnOnce<()>>(self, f: F) -> T {
-   |                                              +++++++++++++++++++++++++++++
-
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/unstable-const-fn-in-libcore.rs:17:53
+  --> $DIR/unstable-const-fn-in-libcore.rs:17:60
    |
-LL |     const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
-   |                                                     ^ constant functions cannot evaluate destructors
+LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
+   |                                                            ^ constant functions cannot evaluate destructors
 ...
 LL |     }
    |     - value is dropped here
 
 error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/unstable-const-fn-in-libcore.rs:17:47
+  --> $DIR/unstable-const-fn-in-libcore.rs:17:54
    |
-LL |     const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
-   |                                               ^^^^ constant functions cannot evaluate destructors
+LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
+   |                                                      ^^^^ constant functions cannot evaluate destructors
 ...
 LL |     }
    |     - value is dropped here
 
-error: aborting due to 3 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/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
index 26986684f0c..81f3f269432 100644
--- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
+++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
@@ -15,13 +15,13 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it
 LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻²
    |                                                     ~
 
-error[E0277]: cannot subtract `{integer}` from `{float}`
+error[E0277]: cannot subtract `{integer}` from `{float}` in const contexts
   --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
    |
 LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
    |                                                     ^ no implementation for `{float} - {integer}`
    |
-   = help: the trait `Sub<{integer}>` is not implemented for `{float}`
+   = help: the trait `~const Sub<{integer}>` is not implemented for `{float}`
    = help: the following other types implement trait `Sub<Rhs>`:
              <&'a f32 as Sub<f32>>
              <&'a f64 as Sub<f64>>
diff --git a/src/test/ui/issues/issue-25901.rs b/src/test/ui/issues/issue-25901.rs
index ba12e1ad021..1f7b341a97e 100644
--- a/src/test/ui/issues/issue-25901.rs
+++ b/src/test/ui/issues/issue-25901.rs
@@ -2,7 +2,7 @@ struct A;
 struct B;
 
 static S: &'static B = &A;
-//~^ ERROR cannot perform deref coercion on `A` in statics
+//~^ ERROR the trait bound
 
 use std::ops::Deref;
 
diff --git a/src/test/ui/issues/issue-25901.stderr b/src/test/ui/issues/issue-25901.stderr
index c6c80e41cf6..b9cac32229a 100644
--- a/src/test/ui/issues/issue-25901.stderr
+++ b/src/test/ui/issues/issue-25901.stderr
@@ -1,23 +1,15 @@
-error[E0015]: cannot perform deref coercion on `A` in statics
+error[E0277]: the trait bound `A: Deref` is not satisfied
   --> $DIR/issue-25901.rs:4:24
    |
 LL | static S: &'static B = &A;
-   |                        ^^
-   |
-   = note: attempting to deref into `B`
-note: deref defined here
-  --> $DIR/issue-25901.rs:10:5
+   |                        ^^ the trait `~const Deref` is not implemented for `A`
    |
-LL |     type Target = B;
-   |     ^^^^^^^^^^^
-note: impl defined here, but it is not `const`
-  --> $DIR/issue-25901.rs:9:1
+note: the trait `Deref` is implemented for `A`, but that implementation is not `const`
+  --> $DIR/issue-25901.rs:4:24
    |
-LL | impl Deref for A {
-   | ^^^^^^^^^^^^^^^^
-   = note: calls in statics are limited to constant functions, tuple structs and tuple variants
-   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+LL | static S: &'static B = &A;
+   |                        ^^
 
 error: aborting due to 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/src/test/ui/issues/issue-50582.stderr b/src/test/ui/issues/issue-50582.stderr
index 3d527eb6b4e..53ecc6112ff 100644
--- a/src/test/ui/issues/issue-50582.stderr
+++ b/src/test/ui/issues/issue-50582.stderr
@@ -7,13 +7,13 @@ LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
    = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
    = help: add `#![feature(const_for)]` to the crate attributes to enable
 
-error[E0277]: cannot add `()` to `{integer}`
+error[E0277]: cannot add `()` to `{integer}` in const contexts
   --> $DIR/issue-50582.rs:2:18
    |
 LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
    |                  ^ no implementation for `{integer} + ()`
    |
-   = help: the trait `Add<()>` is not implemented for `{integer}`
+   = help: the trait `~const Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
              <&'a f32 as Add<f32>>
              <&'a f64 as Add<f64>>
diff --git a/src/test/ui/never_type/issue-52443.rs b/src/test/ui/never_type/issue-52443.rs
index cebcca944af..0498a8a1625 100644
--- a/src/test/ui/never_type/issue-52443.rs
+++ b/src/test/ui/never_type/issue-52443.rs
@@ -9,6 +9,6 @@ fn main() {
     [(); { for _ in 0usize.. {}; 0}];
     //~^ ERROR `for` is not allowed in a `const`
     //~| ERROR cannot convert
-    //~| ERROR mutable references are not allowed in constants
-    //~| ERROR cannot call non-const fn
+    //~| ERROR mutable references
+    //~| ERROR cannot call
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
index 99eacaa837f..7d9dae52cf1 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
@@ -10,6 +10,7 @@ impl std::ops::Add for NonConstAdd {
     }
 }
 
+#[const_trait]
 trait Foo {
     type Bar: ~const std::ops::Add;
 }
@@ -19,6 +20,7 @@ impl const Foo for NonConstAdd {
     //~^ ERROR: cannot add `NonConstAdd` to `NonConstAdd` in const contexts
 }
 
+#[const_trait]
 trait Baz {
     type Qux: std::ops::Add;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
index 64501c52374..ce2425010ad 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -1,17 +1,17 @@
 error[E0277]: cannot add `NonConstAdd` to `NonConstAdd` in const contexts
-  --> $DIR/assoc-type.rs:18:16
+  --> $DIR/assoc-type.rs:19:16
    |
 LL |     type Bar = NonConstAdd;
    |                ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
    |
    = help: the trait `~const Add` is not implemented for `NonConstAdd`
 note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const`
-  --> $DIR/assoc-type.rs:18:16
+  --> $DIR/assoc-type.rs:19:16
    |
 LL |     type Bar = NonConstAdd;
    |                ^^^^^^^^^^^
 note: required by a bound in `Foo::Bar`
-  --> $DIR/assoc-type.rs:14:15
+  --> $DIR/assoc-type.rs:15:15
    |
 LL |     type Bar: ~const std::ops::Add;
    |               ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
index 19e9006094b..589e3f02420 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
@@ -3,6 +3,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait MyTrait {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn func();
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
index 24b9235bb9a..dd993397420 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
@@ -1,5 +1,6 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 pub trait Plus {
     fn plus(self, rhs: Self) -> Self;
 }
@@ -23,7 +24,6 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
 pub const fn add_u32(a: u32, b: u32) -> u32 {
     a.plus(b)
     //~^ ERROR the trait bound
-    //~| ERROR cannot call non-const fn
 }
 
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
index 1fc9db27761..d9ad8043153 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
@@ -1,24 +1,19 @@
 error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
-  --> $DIR/call-const-trait-method-fail.rs:24:7
+  --> $DIR/call-const-trait-method-fail.rs:25:7
    |
 LL |     a.plus(b)
-   |       ^^^^^^^ the trait `~const Plus` is not implemented for `u32`
+   |       ^^^^ the trait `~const Plus` is not implemented for `u32`
    |
 note: the trait `Plus` is implemented for `u32`, but that implementation is not `const`
-  --> $DIR/call-const-trait-method-fail.rs:24:7
+  --> $DIR/call-const-trait-method-fail.rs:25:7
    |
 LL |     a.plus(b)
-   |       ^^^^^^^
-
-error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
-  --> $DIR/call-const-trait-method-fail.rs:24:7
-   |
-LL |     a.plus(b)
-   |       ^^^^^^^
+   |       ^^^^
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: ~const Plus {
+   |                                             ++++++++++++++++++++++
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0015, E0277.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
index cf38bc3c964..b64161b6aa0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
@@ -21,6 +21,7 @@ impl const PartialEq for Int {
     }
 }
 
+#[const_trait]
 pub trait Plus {
     fn plus(self, rhs: Self) -> Self;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs
index 89dc47aad3d..50c46579086 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs
@@ -1,6 +1,7 @@
 // check-pass
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait MyPartialEq {
     fn eq(&self, other: &Self) -> bool;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
index b3e3dd62be8..52984fb6be4 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
@@ -1,6 +1,7 @@
 #![feature(const_trait_impl)]
 
 struct S;
+#[const_trait]
 trait T {
     fn foo();
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr
index 9e49785c589..c8783de4c3e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr
@@ -1,5 +1,5 @@
 error[E0015]: cannot call non-const fn `non_const` in constant functions
-  --> $DIR/const-check-fns-in-const-impl.rs:11:16
+  --> $DIR/const-check-fns-in-const-impl.rs:12:16
    |
 LL |     fn foo() { non_const() }
    |                ^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
index 04462c0a11b..8b4c4065815 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
@@ -48,6 +48,7 @@ mod t {
     pub struct HasConstDrop(pub ConstDrop);
     pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize);
 
+    #[const_trait]
     pub trait SomeTrait {
         fn foo();
     }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs
index 470c653dd47..837124db04e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs
@@ -1,9 +1,11 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Foo {}
 
 const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword
 
+#[const_trait]
 trait Bar {}
 
 const impl<T: Foo> Bar for T {} //~ ERROR: expected identifier, found keyword
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr
index 709084c86e0..7217fc85543 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `impl`
-  --> $DIR/const-impl-recovery.rs:5:7
+  --> $DIR/const-impl-recovery.rs:6:7
    |
 LL | const impl Foo for i32 {}
    |       ^^^^ expected identifier, found keyword
@@ -11,7 +11,7 @@ LL + impl const Foo for i32 {}
    |
 
 error: expected identifier, found keyword `impl`
-  --> $DIR/const-impl-recovery.rs:9:7
+  --> $DIR/const-impl-recovery.rs:11:7
    |
 LL | const impl<T: Foo> Bar for T {}
    |       ^^^^ expected identifier, found keyword
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
new file mode 100644
index 00000000000..1aff0562785
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
@@ -0,0 +1,9 @@
+#![feature(const_trait_impl)]
+
+pub trait A {}
+//~^ NOTE: this trait must be annotated with `#[const_trait]`
+
+impl const A for () {}
+//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]`
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
new file mode 100644
index 00000000000..6b465a9c62e
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
@@ -0,0 +1,14 @@
+error: const `impl`s must be for traits marked with `#[const_trait]`
+  --> $DIR/const-impl-requires-const-trait.rs:6:1
+   |
+LL | impl const A for () {}
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+note: this trait must be annotated with `#[const_trait]`
+  --> $DIR/const-impl-requires-const-trait.rs:3:1
+   |
+LL | pub trait A {}
+   | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr
index af4d3909e40..4c630d33c55 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/feature-gate.rs:13:1
+  --> $DIR/feature-gate.rs:14:1
    |
 LL | fn main() {}
    | ^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs
index 7bac72e1bb6..0b409fbaac9 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.rs
@@ -5,6 +5,7 @@
 #![feature(rustc_attrs)]
 
 struct S;
+#[const_trait] //[stock]~ ERROR `const_trait` is a temporary placeholder
 trait T {}
 impl const T for S {}
 //[stock]~^ ERROR const trait impls are experimental
diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr
index 91a8bb578a8..0e938c1c55d 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr
@@ -1,5 +1,5 @@
 error[E0658]: const trait impls are experimental
-  --> $DIR/feature-gate.rs:9:6
+  --> $DIR/feature-gate.rs:10:6
    |
 LL | impl const T for S {}
    |      ^^^^^
@@ -7,6 +7,15 @@ LL | impl const T for S {}
    = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
    = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future.
+  --> $DIR/feature-gate.rs:8:1
+   |
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs
index 80a4442de2c..337c733403b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 pub trait MyTrait {
     fn method(&self) -> Option<()>;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr
index 32df63e449d..6d2be1daa37 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `?` is not allowed in a `const fn`
-  --> $DIR/hir-const-check.rs:11:9
+  --> $DIR/hir-const-check.rs:12:9
    |
 LL |         Some(())?;
    |         ^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs
index 2cef803a90e..f8ac793e4c1 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl-const-bounds.rs
@@ -3,7 +3,9 @@
 
 struct S;
 
+#[const_trait]
 trait A {}
+#[const_trait]
 trait B {}
 
 impl const A for S {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs
index 1004bb28c59..9f3f38ad4bc 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-100222.rs
@@ -16,6 +16,7 @@ pub trait IndexMut where Self: Index {
 
 impl Index for () { type Output = (); }
 
+#[cfg(not(any(nn, yn)))]
 impl const IndexMut for <() as Index>::Output {
     const C: <Self as Index>::Output = ();
     type Assoc = <Self as Index>::Output;
@@ -24,6 +25,15 @@ impl const IndexMut for <() as Index>::Output {
     {}
 }
 
+#[cfg(any(nn, yn))]
+impl IndexMut for <() as Index>::Output {
+    const C: <Self as Index>::Output = ();
+    type Assoc = <Self as Index>::Output;
+    fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
+        where <Self as Index>::Output:,
+    {}
+}
+
 const C: <() as Index>::Output = ();
 
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs
index 97c27ce1a1c..4d346965394 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs
@@ -4,7 +4,9 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 pub trait Super {}
+#[const_trait]
 pub trait Sub: Super {}
 
 impl<A> const Super for &A where A: ~const Super {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/nested-closure.rs b/src/test/ui/rfc-2632-const-trait-impl/nested-closure.rs
new file mode 100644
index 00000000000..a851136009c
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/nested-closure.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![feature(const_trait_impl, once_cell)]
+
+use std::sync::LazyLock;
+
+static EXTERN_FLAGS: LazyLock<String> = LazyLock::new(|| {
+    let x = || String::new();
+    x()
+});
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs b/src/test/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs
index defef9e0409..1a4509b1869 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Convert<T> {
     fn to(self) -> T;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/static-const-trait-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/static-const-trait-bound.rs
new file mode 100644
index 00000000000..4520a36960c
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/static-const-trait-bound.rs
@@ -0,0 +1,18 @@
+// check-pass
+pub struct S<T, F: FnOnce() -> T = fn() -> T> {
+    f: F,
+    x: Option<T>,
+}
+
+impl<T, F: FnOnce() -> T> S<T, F> {
+    pub const fn new(f: F) -> Self {
+        Self { f, x: None }
+    }
+}
+
+#[derive(Default)]
+pub struct Foo;
+
+static LOCKED_CALLSITES: S<Foo> = S::new(Default::default);
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.rs
index af465cad3d2..3e2b81368a5 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.rs
@@ -1,8 +1,10 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Foo {
     fn a(&self);
 }
+#[const_trait]
 trait Bar: ~const Foo {}
 
 struct S;
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr
index 9e8b8f8c6ba..9787792ab13 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr
@@ -1,16 +1,16 @@
 error[E0277]: the trait bound `S: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail.rs:13:12
+  --> $DIR/super-traits-fail.rs:15:12
    |
 LL | impl const Bar for S {}
    |            ^^^ the trait `~const Foo` is not implemented for `S`
    |
 note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
-  --> $DIR/super-traits-fail.rs:13:12
+  --> $DIR/super-traits-fail.rs:15:12
    |
 LL | impl const Bar for S {}
    |            ^^^
 note: required by a bound in `Bar`
-  --> $DIR/super-traits-fail.rs:6:12
+  --> $DIR/super-traits-fail.rs:8:12
    |
 LL | trait Bar: ~const Foo {}
    |            ^^^^^^^^^^ required by this bound in `Bar`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits.rs
index aded4ca9a99..df96f6fb4ab 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits.rs
@@ -1,9 +1,12 @@
 // check-pass
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Foo {
     fn a(&self);
 }
+
+#[const_trait]
 trait Bar: ~const Foo {}
 
 struct S;
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
new file mode 100644
index 00000000000..7a88ec35c8f
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
@@ -0,0 +1,29 @@
+// Like trait-where-clause.rs, but we are calling from a const context.
+// Checking the validity of traits' where clauses happen at a later stage.
+// (`rustc_const_eval` instead of `rustc_typeck`) Therefore one file as a
+// test is not enough.
+#![feature(const_trait_impl)]
+
+trait Bar {}
+
+trait Foo {
+    fn a();
+    fn b() where Self: ~const Bar;
+    fn c<T: ~const Bar>();
+}
+
+const fn test1<T: ~const Foo + Bar>() {
+    T::a();
+    T::b();
+    //~^ ERROR the trait bound
+    T::c::<T>();
+    //~^ ERROR the trait bound
+}
+
+const fn test2<T: ~const Foo + ~const Bar>() {
+    T::a();
+    T::b();
+    T::c::<T>();
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
new file mode 100644
index 00000000000..13d8639de30
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
@@ -0,0 +1,35 @@
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
+  --> $DIR/trait-where-clause-const.rs:17:5
+   |
+LL |     T::b();
+   |     ^^^^^^ the trait `~const Bar` is not implemented for `T`
+   |
+note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
+  --> $DIR/trait-where-clause-const.rs:17:5
+   |
+LL |     T::b();
+   |     ^^^^^^
+help: consider further restricting this bound
+   |
+LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
+   |                                    ++++++++++++
+
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
+  --> $DIR/trait-where-clause-const.rs:19:5
+   |
+LL |     T::c::<T>();
+   |     ^^^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
+   |
+note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
+  --> $DIR/trait-where-clause-const.rs:19:5
+   |
+LL |     T::c::<T>();
+   |     ^^^^^^^^^^^
+help: consider further restricting this bound
+   |
+LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
+   |                                    ++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs
index b7cf9a13b79..4b8b004069d 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Bar {
     fn bar() -> u8;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
index d37ed3bb8dd..5bd23a8cb20 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
@@ -8,7 +8,7 @@ trait Foo {
     fn c<T: ~const Bar>();
 }
 
-const fn test1<T: ~const Foo + Bar>() {
+fn test1<T: Foo>() {
     T::a();
     T::b();
     //~^ ERROR the trait bound
@@ -16,21 +16,7 @@ const fn test1<T: ~const Foo + Bar>() {
     //~^ ERROR the trait bound
 }
 
-const fn test2<T: ~const Foo + ~const Bar>() {
-    T::a();
-    T::b();
-    T::c::<T>();
-}
-
-fn test3<T: Foo>() {
-    T::a();
-    T::b();
-    //~^ ERROR the trait bound
-    T::c::<T>();
-    //~^ ERROR the trait bound
-}
-
-fn test4<T: Foo + Bar>() {
+fn test2<T: Foo + Bar>() {
     T::a();
     T::b();
     T::c::<T>();
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index fd5fe25ddcf..96365d33433 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -1,47 +1,5 @@
-error[E0277]: the trait bound `T: ~const Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:13:5
-   |
-LL |     T::b();
-   |     ^^^^ the trait `~const Bar` is not implemented for `T`
-   |
-note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/trait-where-clause.rs:13:5
-   |
-LL |     T::b();
-   |     ^^^^
-note: required by a bound in `Foo::b`
-  --> $DIR/trait-where-clause.rs:7:24
-   |
-LL |     fn b() where Self: ~const Bar;
-   |                        ^^^^^^^^^^ required by this bound in `Foo::b`
-help: consider further restricting this bound
-   |
-LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
-   |                                    ++++++++++++
-
-error[E0277]: the trait bound `T: ~const Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:15:12
-   |
-LL |     T::c::<T>();
-   |            ^ the trait `~const Bar` is not implemented for `T`
-   |
-note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/trait-where-clause.rs:15:12
-   |
-LL |     T::c::<T>();
-   |            ^
-note: required by a bound in `Foo::c`
-  --> $DIR/trait-where-clause.rs:8:13
-   |
-LL |     fn c<T: ~const Bar>();
-   |             ^^^^^^^^^^ required by this bound in `Foo::c`
-help: consider further restricting this bound
-   |
-LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
-   |                                    ++++++++++++
-
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:27:5
+  --> $DIR/trait-where-clause.rs:13:5
    |
 LL |     T::b();
    |     ^^^^ the trait `Bar` is not implemented for `T`
@@ -53,11 +11,11 @@ LL |     fn b() where Self: ~const Bar;
    |                        ^^^^^^^^^^ required by this bound in `Foo::b`
 help: consider further restricting this bound
    |
-LL | fn test3<T: Foo + Bar>() {
+LL | fn test1<T: Foo + Bar>() {
    |                 +++++
 
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:29:12
+  --> $DIR/trait-where-clause.rs:15:12
    |
 LL |     T::c::<T>();
    |            ^ the trait `Bar` is not implemented for `T`
@@ -69,9 +27,9 @@ LL |     fn c<T: ~const Bar>();
    |             ^^^^^^^^^^ required by this bound in `Foo::c`
 help: consider further restricting this bound
    |
-LL | fn test3<T: Foo + Bar>() {
+LL | fn test1<T: Foo + Bar>() {
    |                 +++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/stability-attribute/missing-const-stability.rs b/src/test/ui/stability-attribute/missing-const-stability.rs
index d89886af314..6eff899bfbf 100644
--- a/src/test/ui/stability-attribute/missing-const-stability.rs
+++ b/src/test/ui/stability-attribute/missing-const-stability.rs
@@ -19,6 +19,7 @@ impl Foo {
 }
 
 #[stable(feature = "stable", since = "1.0.0")]
+#[const_trait]
 pub trait Bar {
     #[stable(feature = "stable", since = "1.0.0")]
     fn fun();
diff --git a/src/test/ui/stability-attribute/missing-const-stability.stderr b/src/test/ui/stability-attribute/missing-const-stability.stderr
index 10978728fa3..4cfbe152891 100644
--- a/src/test/ui/stability-attribute/missing-const-stability.stderr
+++ b/src/test/ui/stability-attribute/missing-const-stability.stderr
@@ -5,7 +5,7 @@ LL | pub const fn foo() {}
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: implementation has missing const stability attribute
-  --> $DIR/missing-const-stability.rs:27:1
+  --> $DIR/missing-const-stability.rs:28:1
    |
 LL | / impl const Bar for Foo {
 LL | |