about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-08 19:23:41 +0000
committerbors <bors@rust-lang.org>2023-08-08 19:23:41 +0000
commitf88a8b71cebb730cbd5058c45ebcae1d4d9be377 (patch)
treecb6151402989f498dd13def70bbab6d54dc50878
parentf525bb4e2afac6d2491a86c178aa98e3f3931130 (diff)
parent057be381c60bf9b5c26497a42ad51917c3027b65 (diff)
downloadrust-f88a8b71cebb730cbd5058c45ebcae1d4d9be377.tar.gz
rust-f88a8b71cebb730cbd5058c45ebcae1d4d9be377.zip
Auto merge of #114545 - fee1-dead-contrib:lower-impl-effect, r=oli-obk
correctly lower `impl const` to bind to host effect param

r? `@oli-obk`
-rw-r--r--compiler/rustc_ast/src/ast.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs84
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs95
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs13
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs11
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs7
-rw-r--r--compiler/rustc_hir/src/hir.rs1
-rw-r--r--compiler/rustc_hir/src/intravisit.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs3
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_passes/src/stability.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs21
-rw-r--r--tests/ui/const-generics/const_trait_fn-issue-88433.rs2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr42
-rw-r--r--tests/ui/consts/const-try.stderr33
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.rs2
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr28
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr27
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs7
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr23
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs1
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr40
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs6
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr17
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr33
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs2
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.rs2
64 files changed, 463 insertions, 371 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f2e90fd8eed..58725a08c7c 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -313,6 +313,16 @@ pub enum TraitBoundModifier {
     MaybeConstMaybe,
 }
 
+impl TraitBoundModifier {
+    pub fn to_constness(self) -> Const {
+        match self {
+            // FIXME(effects) span
+            Self::MaybeConst => Const::Yes(DUMMY_SP),
+            _ => Const::No,
+        }
+    }
+}
+
 /// The AST represents all type param bounds as types.
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index ab55c09465b..a1e62699680 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -207,6 +207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 &sym.path,
                                 ParamMode::Optional,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                                None,
                             );
                             hir::InlineAsmOperand::SymStatic { path, def_id }
                         } else {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 42d0998d162..b23cee14f75 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -100,6 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ParamMode::Optional,
                         ParenthesizedGenericArgs::Err,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     ));
                     let receiver = self.lower_expr(receiver);
                     let args =
@@ -260,6 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     hir::ExprKind::Path(qpath)
                 }
@@ -307,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         )),
                         self.arena
                             .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -1179,6 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a tuple struct.
                     let tuple_struct_pat = hir::PatKind::TupleStruct(
@@ -1198,6 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a unit struct.
                     let unit_struct_pat = hir::PatKind::Path(qpath);
@@ -1222,6 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.path,
                     ParamMode::Optional,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 );
                 let fields_omitted = match &se.rest {
                     StructRest::Base(e) => {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index df73c721ade..7954297900f 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
             allow_gen_future,
             generics_def_id_map: Default::default(),
+            host_param_id: None,
         };
         lctx.with_hir_id_owner(owner, |lctx| f(lctx));
 
@@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             // This is used to track which lifetimes have already been defined,
             // and which need to be replicated when lowering an async fn.
 
-            if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind {
-                lctx.is_in_trait_impl = impl_.of_trait.is_some();
+            match parent_hir.node().expect_item().kind {
+                hir::ItemKind::Impl(impl_) => {
+                    lctx.is_in_trait_impl = impl_.of_trait.is_some();
+                }
+                hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => {
+                    lctx.host_param_id = generics
+                        .params
+                        .iter()
+                        .find(|param| {
+                            parent_hir
+                                .attrs
+                                .get(param.hir_id.local_id)
+                                .iter()
+                                .any(|attr| attr.has_name(sym::rustc_host))
+                        })
+                        .map(|param| param.def_id);
+                }
+                _ => {}
             }
 
             match ctxt {
@@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.lower_generics(ast_generics, *constness, id, &itctx, |this| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(
+                                *constness,
                                 trait_ref,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
                             )
@@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     polarity,
                     defaultness,
                     defaultness_span,
-                    constness: self.lower_constness(*constness),
                     generics,
                     of_trait: trait_ref,
                     self_ty: lowered_ty,
@@ -1363,6 +1380,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         }
 
+        // Desugar `~const` bound in generics into an additional `const host: bool` param
+        // if the effects feature is enabled. This needs to be done before we lower where
+        // clauses since where clauses need to bind to the DefId of the host param
+        let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects {
+            if let Some(param) = generics.params.iter().find(|x| {
+                x.attrs.iter().any(|x| x.has_name(sym::rustc_host))
+            }) {
+                // user has manually specified a `rustc_host` param, in this case, we set
+                // the param id so that lowering logic can use that. But we don't create
+                // another host param, so this gives `None`.
+                self.host_param_id = Some(self.local_def_id(param.id));
+                None
+            } else {
+                let param_node_id = self.next_node_id();
+                let hir_id = self.next_id();
+                let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
+                self.host_param_id = Some(def_id);
+                Some((span, hir_id, def_id))
+            }
+        } else {
+            None
+        };
+
         let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
         predicates.extend(generics.params.iter().filter_map(|param| {
             self.lower_generic_bound_predicate(
@@ -1410,22 +1450,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
         predicates.extend(impl_trait_bounds.into_iter());
 
-        // Desugar `~const` bound in generics into an additional `const host: bool` param
-        // if the effects feature is enabled.
-        if let Const::Yes(span) = constness && self.tcx.features().effects
-            // Do not add host param if it already has it (manually specified)
-            && !params.iter().any(|x| {
-                self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| {
-                    attrs.iter().any(|x| x.has_name(sym::rustc_host))
-                })
-            })
-        {
-            let param_node_id = self.next_node_id();
+        if let Some((span, hir_id, def_id)) = host_param_parts {
             let const_node_id = self.next_node_id();
-            let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
-            let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
+            let anon_const: LocalDefId =
+                self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
 
-            let hir_id = self.next_id();
             let const_id = self.next_id();
             let const_expr_id = self.next_id();
             let bool_id = self.next_id();
@@ -1435,14 +1464,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
 
-            let attrs = self.arena.alloc_from_iter([
-                Attribute {
-                    kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            let attrs = self.arena.alloc_from_iter([Attribute {
+                kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(
+                    sym::rustc_host,
                     span,
-                    id: attr_id,
-                    style: AttrStyle::Outer,
-                },
-            ]);
+                )))),
+                span,
+                id: attr_id,
+                style: AttrStyle::Outer,
+            }]);
             self.attrs.insert(hir_id.local_id, attrs);
 
             let const_body = self.lower_body(|this| {
@@ -1481,7 +1511,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             }),
                         )),
                     )),
-                    default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }),
+                    default: Some(hir::AnonConst {
+                        def_id: anon_const,
+                        hir_id: const_id,
+                        body: const_body,
+                    }),
                 },
                 colon_span: None,
                 pure_wrt_drop: false,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index a8151ccfff3..0aeff22ca9f 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> {
     /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
     /// field from the original parameter 'a to the new parameter 'a1.
     generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
+
+    host_param_id: Option<LocalDefId>,
 }
 
 trait ResolverAstLoweringExt {
@@ -1262,6 +1264,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         span: t.span
                     },
                     itctx,
+                    ast::Const::No,
                 );
                 let bounds = this.arena.alloc_from_iter([bound]);
                 let lifetime_bound = this.elided_dyn_bound(t.span);
@@ -1272,7 +1275,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         let id = self.lower_node_id(t.id);
-        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
+        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None);
         self.ty_path(id, t.span, qpath)
     }
 
@@ -1356,10 +1359,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
                             GenericBound::Trait(
                                 ty,
-                                TraitBoundModifier::None
+                                modifier @ (TraitBoundModifier::None
                                 | TraitBoundModifier::MaybeConst
-                                | TraitBoundModifier::Negative,
-                            ) => Some(this.lower_poly_trait_ref(ty, itctx)),
+                                | TraitBoundModifier::Negative),
+                            ) => {
+                                Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness()))
+                            }
                             // `~const ?Bound` will cause an error during AST validation
                             // anyways, so treat it like `?Bound` as compilation proceeds.
                             GenericBound::Trait(
@@ -1952,7 +1957,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(p, itctx),
+                self.lower_poly_trait_ref(p, itctx, modifier.to_constness()),
                 self.lower_trait_bound_modifier(*modifier),
             ),
             GenericBound::Outlives(lifetime) => {
@@ -2095,8 +2100,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> {
-        let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
+    fn lower_trait_ref(
+        &mut self,
+        constness: ast::Const,
+        p: &TraitRef,
+        itctx: &ImplTraitContext,
+    ) -> hir::TraitRef<'hir> {
+        let path = match self.lower_qpath(
+            p.ref_id,
+            &None,
+            &p.path,
+            ParamMode::Explicit,
+            itctx,
+            Some(constness),
+        ) {
             hir::QPath::Resolved(None, path) => path,
             qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
         };
@@ -2108,10 +2125,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         p: &PolyTraitRef,
         itctx: &ImplTraitContext,
+        constness: ast::Const,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
             self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
-        let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx);
+        let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx);
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
     }
 
@@ -2465,6 +2483,67 @@ struct GenericArgsCtor<'hir> {
 }
 
 impl<'hir> GenericArgsCtor<'hir> {
+    fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) {
+        if !lcx.tcx.features().effects {
+            return;
+        }
+
+        // if bound is non-const, don't add host effect param
+        let ast::Const::Yes(span) = constness else { return };
+
+        let span = lcx.lower_span(span);
+
+        let id = lcx.next_node_id();
+        let hir_id = lcx.next_id();
+        let body = lcx.lower_body(|lcx| {
+            (
+                &[],
+                match constness {
+                    ast::Const::Yes(_) => {
+                        let hir_id = lcx.next_id();
+                        let res =
+                            Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id());
+                        let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved(
+                            None,
+                            lcx.arena.alloc(hir::Path {
+                                span,
+                                res,
+                                segments: arena_vec![lcx; hir::PathSegment::new(Ident {
+                                    name: sym::host,
+                                    span,
+                                }, hir_id, res)],
+                            }),
+                        ));
+                        lcx.expr(span, expr_kind)
+                    }
+                    ast::Const::No => lcx.expr(
+                        span,
+                        hir::ExprKind::Lit(
+                            lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }),
+                        ),
+                    ),
+                },
+            )
+        });
+
+        let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
+        let attr = lcx.arena.alloc(Attribute {
+            kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            span,
+            id: attr_id,
+            style: AttrStyle::Outer,
+        });
+        lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr));
+
+        let def_id =
+            lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span);
+        lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
+        self.args.push(hir::GenericArg::Const(hir::ConstArg {
+            value: hir::AnonConst { def_id, hir_id, body },
+            span,
+        }))
+    }
+
     fn is_empty(&self) -> bool {
         self.args.is_empty()
             && self.bindings.is_empty()
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2509b705639..a30f264bc7d 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                         break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -54,6 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         break hir::PatKind::Path(qpath);
                     }
@@ -64,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
 
                         let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 441282c05b4..899f92a9958 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -23,6 +23,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Path,
         param_mode: ParamMode,
         itctx: &ImplTraitContext,
+        // constness of the impl/bound if this is a trait path
+        constness: Option<ast::Const>,
     ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
@@ -73,6 +75,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         param_mode,
                         parenthesized_generic_args,
                         itctx,
+                        // if this is the last segment, add constness to the trait path
+                        if i == proj_start - 1 { constness } else { None },
                     )
                 },
             )),
@@ -119,6 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 param_mode,
                 ParenthesizedGenericArgs::Err,
                 itctx,
+                None,
             ));
             let qpath = hir::QPath::TypeRelative(ty, hir_segment);
 
@@ -159,6 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     param_mode,
                     ParenthesizedGenericArgs::Err,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 )
             })),
             span: self.lower_span(p.span),
@@ -172,8 +178,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         param_mode: ParamMode,
         parenthesized_generic_args: ParenthesizedGenericArgs,
         itctx: &ImplTraitContext,
+        constness: Option<ast::Const>,
     ) -> hir::PathSegment<'hir> {
-        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
+        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment);
         let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
             match generic_args {
                 GenericArgs::AngleBracketed(data) => {
@@ -231,6 +238,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             )
         };
 
+        if let Some(constness) = constness {
+            generic_args.push_constness(self, constness);
+        }
+
         let has_lifetimes =
             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
 
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index cc39387c41f..4ee4ebbb9e4 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -40,7 +40,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
         | hir::Node::AnonConst(_)
         | hir::Node::ConstBlock(_)
         | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const,
-        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const),
         hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
             // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
             // foreign items cannot be evaluated at compile-time.
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index e77fb4ea2a2..e51082e1ec0 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -127,15 +127,8 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let hir_id = tcx.local_def_id_to_hir_id(local_def_id);
 
     let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false };
-    let parent_def = tcx.hir().get(parent);
-
-    if !matches!(
-        parent_def,
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
-            ..
-        })
-    ) {
+
+    if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) {
         return false;
     }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index e785196c744..1f3cda35c2b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -145,8 +145,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                     let implsrc = selcx.select(&obligation);
 
                     if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
-                        let span = tcx.def_span(data.impl_def_id);
-                        err.subdiagnostic(errors::NonConstImplNote { span });
+                        // FIXME(effects) revisit this
+                        if !tcx.is_const_trait_impl_raw(data.impl_def_id) {
+                            let span = tcx.def_span(data.impl_def_id);
+                            err.subdiagnostic(errors::NonConstImplNote { span });
+                        }
                     }
                 }
                 _ => {}
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 61353c7b1ec..92a91766d91 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3359,7 +3359,6 @@ pub struct Impl<'hir> {
     // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
     // decoding as `Span`s cannot be decoded when a `Session` is not available.
     pub defaultness_span: Option<Span>,
-    pub constness: Constness,
     pub generics: &'hir Generics<'hir>,
 
     /// The trait being implemented, if any.
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9d1d899eef0..172f557f8e2 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -522,7 +522,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
             unsafety: _,
             defaultness: _,
             polarity: _,
-            constness: _,
             defaultness_span: _,
             ref generics,
             ref of_trait,
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 319573c85b4..668763f9bf6 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -532,6 +532,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         if let Err(guar) = ty.error_reported() {
                             return ty::Const::new_error(tcx, guar, ty).into();
                         }
+                        // FIXME(effects) see if we should special case effect params here
                         if !infer_args && has_default {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, args.unwrap())
@@ -659,7 +660,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         trait_ref: &hir::TraitRef<'_>,
         self_ty: Ty<'tcx>,
-        constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
 
@@ -669,7 +669,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             self_ty,
             trait_ref.path.segments.last().unwrap(),
             true,
-            constness,
+            ty::BoundConstness::NotConst,
         )
     }
 
@@ -849,6 +849,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         self_ty: Ty<'tcx>,
         trait_segment: &hir::PathSegment<'_>,
         is_impl: bool,
+        // FIXME(effects) move all host param things in astconv to hir lowering
         constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         let (generic_args, _) = self.create_args_for_ast_trait_ref(
@@ -2714,11 +2715,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         };
         let i = hir.get_parent(fn_hir_id).expect_item().expect_impl();
 
-        let trait_ref = self.instantiate_mono_trait_ref(
-            i.of_trait.as_ref()?,
-            self.ast_ty_to_ty(i.self_ty),
-            ty::BoundConstness::NotConst,
-        );
+        let trait_ref =
+            self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
 
         let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index f568b751951..02a5d28b1e2 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1359,38 +1359,60 @@ fn impl_trait_ref(
         .as_ref()
         .map(|ast_trait_ref| {
             let selfty = tcx.type_of(def_id).instantiate_identity();
-            icx.astconv().instantiate_mono_trait_ref(
-                ast_trait_ref,
-                selfty,
-                check_impl_constness(tcx, impl_.constness, ast_trait_ref),
-            )
+
+            if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
+                tcx,
+                tcx.is_const_trait_impl_raw(def_id.to_def_id()),
+                &ast_trait_ref,
+            ) {
+                // we have a const impl, but for a trait without `#[const_trait]`, so
+                // without the host param. If we continue with the HIR trait ref, we get
+                // ICEs for generic arg count mismatch. We do a little HIR editing to
+                // make astconv happy.
+                let mut path_segments = ast_trait_ref.path.segments.to_vec();
+                let last_segment = path_segments.len() - 1;
+                let mut args = path_segments[last_segment].args().clone();
+                let last_arg = args.args.len() - 1;
+                assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host)));
+                args.args = &args.args[..args.args.len() - 1];
+                path_segments[last_segment].args = Some(&args);
+                let path = hir::Path {
+                    span: ast_trait_ref.path.span,
+                    res: ast_trait_ref.path.res,
+                    segments: &path_segments,
+                };
+                let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id };
+                icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty)
+            } else {
+                icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty)
+            }
         })
         .map(ty::EarlyBinder::bind)
 }
 
 fn check_impl_constness(
     tcx: TyCtxt<'_>,
-    constness: hir::Constness,
+    is_const: bool,
     ast_trait_ref: &hir::TraitRef<'_>,
-) -> ty::BoundConstness {
-    match constness {
-        hir::Constness::Const => {
-            if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
-                let trait_name = tcx.item_name(trait_def_id).to_string();
-                tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
-                    trait_ref_span: ast_trait_ref.path.span,
-                    trait_name,
-                    local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
-                    marking: (),
-                    adding: (),
-                });
-                ty::BoundConstness::NotConst
-            } else {
-                ty::BoundConstness::ConstIfConst
-            }
-        },
-        hir::Constness::NotConst => ty::BoundConstness::NotConst,
+) -> Option<ErrorGuaranteed> {
+    if !is_const {
+        return None;
     }
+
+    let trait_def_id = ast_trait_ref.trait_def_id()?;
+    if tcx.has_attr(trait_def_id, sym::const_trait) {
+        return None;
+    }
+
+    let trait_name = tcx.item_name(trait_def_id).to_string();
+    Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
+        trait_ref_span: ast_trait_ref.path.span,
+        trait_name,
+        local_trait_span:
+            trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
+        marking: (),
+        adding: (),
+    }))
 }
 
 fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 6e1762c54f2..4842008279a 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
                 }
 
-                host_effect_index = Some(parent_count + index as usize);
+                host_effect_index = Some(index as usize);
             }
 
             Some(ty::GenericParamDef {
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 6be8d72aed2..61b182b1be7 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -578,6 +578,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             MissingTypesOrConsts { .. } => {
                 self.suggest_adding_type_and_const_args(err);
             }
+            ExcessTypesOrConsts { .. } => {
+                // this can happen with `~const T` where T isn't a const_trait.
+            }
             _ => unreachable!(),
         }
     }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index fda46798708..89efdc269c4 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -626,7 +626,6 @@ impl<'a> State<'a> {
                 unsafety,
                 polarity,
                 defaultness,
-                constness,
                 defaultness_span: _,
                 generics,
                 ref of_trait,
@@ -643,10 +642,6 @@ impl<'a> State<'a> {
                     self.space();
                 }
 
-                if constness == hir::Constness::Const {
-                    self.word_nbsp("const");
-                }
-
                 if let hir::ImplPolarity::Negative(_) = polarity {
                     self.word("!");
                 }
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index c68f2d94f35..ba00954db91 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -767,9 +767,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let tcx = self.tcx;
 
-        if !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you {
-            return;
-        }
+        // fast-reject if callee doesn't have the host effect param (non-const)
+        let generics = tcx.generics_of(callee_did);
+        let Some(host_effect_index) = generics.host_effect_index else { return };
+
+        // if the callee does have the param, we need to equate the param to some const
+        // value no matter whether the effects feature is enabled in the local crate,
+        // because inference will fail if we don't.
+        let mut host_always_on =
+            !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
 
         // Compute the constness required by the context.
         let context = tcx.hir().enclosing_body_owner(call_expr_hir);
@@ -780,10 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if tcx.has_attr(context.to_def_id(), sym::rustc_do_not_const_check) {
             trace!("do not const check this context");
-            return;
+            host_always_on = true;
         }
 
         let effect = match const_context {
+            _ if host_always_on => tcx.consts.true_,
             Some(hir::ConstContext::Static(_) | hir::ConstContext::Const) => tcx.consts.false_,
             Some(hir::ConstContext::ConstFn) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, context);
@@ -792,21 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             None => tcx.consts.true_,
         };
 
-        let generics = tcx.generics_of(callee_did);
-
         trace!(?effect, ?generics, ?callee_args);
 
-        if let Some(idx) = generics.host_effect_index {
-            let param = callee_args.const_at(idx);
-            let cause = self.misc(span);
-            match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
-                Ok(infer::InferOk { obligations, value: () }) => {
-                    self.register_predicates(obligations);
-                }
-                Err(e) => {
-                    // FIXME(effects): better diagnostic
-                    self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
-                }
+        let param = callee_args.const_at(host_effect_index);
+        let cause = self.misc(span);
+        match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
+            Ok(infer::InferOk { obligations, value: () }) => {
+                self.register_predicates(obligations);
+            }
+            Err(e) => {
+                // FIXME(effects): better diagnostic
+                self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 322d726a89d..8fad0a6c9e4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1349,7 +1349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     GenericParamDefKind::Const { has_default } => {
-                        if !infer_args && has_default {
+                        if !infer_args
+                            && has_default
+                            && !tcx.has_attr(param.def_id, sym::rustc_host)
+                        {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, args.unwrap())
                                 .into()
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 6446f48bd1a..8ac1d02ce50 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2041,9 +2041,9 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(
             node,
             hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
+                kind: hir::ItemKind::Impl(hir::Impl { generics, .. }),
                 ..
-            })
+            }) if generics.params.iter().any(|p| self.has_attr(p.def_id, sym::rustc_host))
         )
     }
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 27ade16739d..e5b4232431b 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2841,6 +2841,11 @@ define_print_and_forward_display! {
 
     ty::TraitPredicate<'tcx> {
         p!(print(self.trait_ref.self_ty()), ": ");
+        if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index {
+            if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ {
+                p!("~const ");
+            }
+        }
         // FIXME(effects) print `~const` here
         if let ty::ImplPolarity::Negative = self.polarity {
             p!("!");
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 25a3d38c144..3950ac9dd31 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -732,13 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
             // For implementations of traits, check the stability of each item
             // individually as it's possible to have a stable trait with unstable
             // items.
-            hir::ItemKind::Impl(hir::Impl {
-                of_trait: Some(ref t),
-                self_ty,
-                items,
-                constness,
-                ..
-            }) => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
                 let features = self.tcx.features();
                 if features.staged_api {
                     let attrs = self.tcx.hir().attrs(item.hir_id());
@@ -769,7 +763,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                     // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
                     // needs to have an error emitted.
                     if features.const_trait_impl
-                        && *constness == hir::Constness::Const
+                        && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id())
                         && const_stab.is_some_and(|(stab, _)| stab.is_const_stable())
                     {
                         self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span });
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 4d85e2b6089..64784082992 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -3110,27 +3110,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> UnsatisfiedConst {
         let unsatisfied_const = UnsatisfiedConst(false);
         // FIXME(effects)
-        /* if trait_predicate.is_const_if_const() {
-            let non_const_predicate = trait_ref.without_const();
-            let non_const_obligation = Obligation {
-                cause: obligation.cause.clone(),
-                param_env: obligation.param_env,
-                predicate: non_const_predicate.to_predicate(self.tcx),
-                recursion_depth: obligation.recursion_depth,
-            };
-            if self.predicate_may_hold(&non_const_obligation) {
-                unsatisfied_const = UnsatisfiedConst(true);
-                err.span_note(
-                    span,
-                    format!(
-                        "the trait `{}` is implemented for `{}`, \
-                        but that implementation is not `const`",
-                        non_const_predicate.print_modifiers_and_trait_path(),
-                        trait_ref.skip_binder().self_ty(),
-                    ),
-                );
-            }
-        } */
         unsatisfied_const
     }
 
diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs
index 6e04cfaec31..88dff919206 100644
--- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs
+++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs
@@ -1,6 +1,6 @@
 // build-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Func<T> {
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
index 7f28771cee8..eb71ebb62eb 100644
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -1,11 +1,39 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/unify-op-with-fn-call.rs:10:12
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:18:29
    |
-LL | impl const std::ops::Add for Foo {
-   |            ^^^^^^^^^^^^^
+LL | struct Evaluatable<const N: Foo>;
+   |                             ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
+   |
+
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:20:17
+   |
+LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
+   |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
+   |
+
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:24:17
+   |
+LL | fn bar<const N: Foo>() {}
+   |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr
index 37014f9b83f..94f4153a29e 100644
--- a/tests/ui/consts/const-try.stderr
+++ b/tests/ui/consts/const-try.stderr
@@ -1,20 +1,29 @@
-error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
-  --> $DIR/const-try.rs:15:12
+error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions
+  --> $DIR/const-try.rs:33:5
    |
-LL | impl const FromResidual<Error> for TryMe {
-   |            ^^^^^^^^^^^^^^^^^^^
+LL |     TryMe?;
+   |     ^^^^^^
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
-  --> $DIR/const-try.rs:21:12
+note: impl defined here, but it is not `const`
+  --> $DIR/const-try.rs:21:1
    |
 LL | impl const Try for TryMe {
-   |            ^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions
+  --> $DIR/const-try.rs:33:5
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL |     TryMe?;
+   |     ^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/const-try.rs:15:1
+   |
+LL | impl const FromResidual<Error> for TryMe {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs
index a1a741e80e5..2b67c2f2cff 100644
--- a/tests/ui/consts/rustc-impl-const-stability.rs
+++ b/tests/ui/consts/rustc-impl-const-stability.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 #![feature(staged_api)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![stable(feature = "foo", since = "1.0.0")]
 
 #[stable(feature = "potato", since = "1.27.0")]
diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr
index e6930da71ec..ba8e6c1555c 100644
--- a/tests/ui/consts/rustc-impl-const-stability.stderr
+++ b/tests/ui/consts/rustc-impl-const-stability.stderr
@@ -7,5 +7,15 @@ LL | impl const Default for Data {
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to previous error
+error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/rustc-impl-const-stability.rs:15:6
+   |
+LL | impl const Default for Data {
+   |      ^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
index e73082c1127..f40dc27cb4c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait MyTrait {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
index 589e3f02420..687cb128b05 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
index 646955fd867..771c35cf6ab 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait Plus {
@@ -23,7 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
 
 pub const fn add_u32(a: u32, b: u32) -> u32 {
     a.plus(b)
-    //~^ ERROR cannot call
+    //~^ ERROR the trait bound
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
index 0ee1b1a5cb2..2d9c49af85a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
+error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
   --> $DIR/call-const-trait-method-fail.rs:25:7
    |
 LL |     a.plus(b)
-   |       ^^^^^^^
+   |       ^^^^ the trait `Plus` is not implemented for `u32`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `Plus` is implemented for `u32`
 
 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/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
index ff53eea1110..60cd000f2d8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
@@ -1,20 +1,24 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:7:12
+error[E0015]: cannot call non-const fn `<i32 as Plus>::plus` in constant functions
+  --> $DIR/call-const-trait-method-pass.rs:36:7
    |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
+LL |     a.plus(b)
+   |       ^^^^^^^
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:15:12
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/call-const-trait-method-pass.rs:39:22
+   |
+LL | const ADD_INT: Int = Int(1i32) + Int(2i32);
+   |                      ^^^^^^^^^^^^^^^^^^^^^
    |
-LL | impl const PartialEq for Int {
-   |            ^^^^^^^^^
+note: impl defined here, but it is not `const`
+  --> $DIR/call-const-trait-method-pass.rs:7:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const std::ops::Add for Int {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
index 529a472e0bd..37faa3f6bce 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-chain.rs:9:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-chain.rs:18:32
    |
@@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
    |                                        ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
index bdc6ccc8aec..90cfe04a9a8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-dup-bound.rs:7:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-dup-bound.rs:18:44
    |
@@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
    |                                     ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
index 7fbe89dba3c..bea1846e79b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
@@ -1,17 +1,8 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-pass.rs:9:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-pass.rs:18:32
    |
 LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
    |                                ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
index 4f858d61eeb..54bc4347722 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
@@ -1,20 +1,25 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:7:12
+error[E0117]: only traits defined in the current crate can be implemented for primitive types
+  --> $DIR/const-and-non-const-impl.rs:7:1
    |
 LL | impl const std::ops::Add for i32 {
-   |            ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^-------------^^^^^---
+   | |          |                 |
+   | |          |                 `i32` is not defined in the current crate
+   | |          `i32` is not defined in the current crate
+   | impl doesn't use only types from inside the current crate
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: define and implement a trait or new type instead
 
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:23:12
+error[E0119]: conflicting implementations of trait `Add` for type `Int`
+  --> $DIR/const-and-non-const-impl.rs:23:1
    |
+LL | impl std::ops::Add for Int {
+   | -------------------------- first implementation here
+...
 LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int`
 
 error: aborting due to 2 previous errors
 
+Some errors have detailed explanations: E0117, E0119.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
index 52984fb6be4..4854f41bf04 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 struct S;
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
index 3370f32061c..be668b4f13a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait ConstDefaultFn: Sized {
@@ -22,7 +22,7 @@ impl const ConstDefaultFn for ConstImpl {
 
 const fn test() {
     NonConstImpl.a();
-    //~^ ERROR cannot call
+    //~^ ERROR the trait bound
     ConstImpl.a();
 }
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
index 414688f71ed..7b558e3f773 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
+error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
   --> $DIR/const-default-method-bodies.rs:24:18
    |
 LL |     NonConstImpl.a();
-   |                  ^^^
+   |                  ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl`
 
 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/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
index 3de9d37d493..747ccbf0fab 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
@@ -18,6 +18,10 @@ trait A { fn a() { } }
 
 impl A for NonTrivialDrop {}
 
+const fn check<T: ~const Destruct>(_: T) {}
+
+
+/* FIXME(effects)
 struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
 
 impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
@@ -26,11 +30,10 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
     }
 }
 
-const fn check<T: ~const Destruct>(_: T) {}
-
 const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
     ConstDropImplWithBounds(PhantomData)
 );
+*/
 
 struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
index 7de33003c48..100d1df87d6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
@@ -1,28 +1,11 @@
-error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
-  --> $DIR/const-drop-fail-2.rs:25:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop-fail-2.rs:29:36
+  --> $DIR/const-drop-fail-2.rs:21:36
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                                    ^      - value is dropped here
    |                                    |
    |                                    the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
-  --> $DIR/const-drop-fail-2.rs:39:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-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/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
index b28584e7e36..23e36887025 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
@@ -14,15 +14,6 @@ LL |     let _ = S(&mut c);
    |             |
    |             the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
-  --> $DIR/const-drop.rs:70:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-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/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
index b28584e7e36..23e36887025 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
@@ -14,15 +14,6 @@ LL |     let _ = S(&mut c);
    |             |
    |             the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
-  --> $DIR/const-drop.rs:70:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-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/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
index 2b4963991db..fc3a83876c5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
@@ -1,9 +1,11 @@
-#![feature(const_trait_impl)]
+// known-bug: #110395
+
+#![feature(const_trait_impl, effects)]
 
 pub trait A {}
-//~^ HELP: mark `A` as const
+// FIXME ~^ HELP: mark `A` as const
 
 impl const A for () {}
-//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
+// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
index 478adcf3e9e..c45af1a9f8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
@@ -1,5 +1,5 @@
 error: const `impl` for trait `A` which is not marked with `#[const_trait]`
-  --> $DIR/const-impl-requires-const-trait.rs:6:12
+  --> $DIR/const-impl-requires-const-trait.rs:8:12
    |
 LL | pub trait A {}
    | - help: mark `A` as const: `#[const_trait]`
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
index dba3ad7f870..348ca0ab190 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
@@ -1,5 +1,4 @@
 #[derive_const(Default)] //~ ERROR use of unstable library feature
-//~^ ERROR not marked with `#[const_trait]`
 pub struct S;
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
index 6a81f96d88d..cc9bdd2715f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
@@ -6,16 +6,6 @@ LL | #[derive_const(Default)]
    |
    = help: add `#![feature(derive_const)]` to the crate attributes to enable
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-gate.rs:1:16
-   |
-LL | #[derive_const(Default)]
-   |                ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
index b575ea8dae2..ce39045d71b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
@@ -1,5 +1,5 @@
 // known-bug: #110395
-#![feature(derive_const)]
+#![feature(derive_const, effects)]
 
 pub struct A;
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
index 88054096e63..046dbae0eae 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
@@ -10,44 +10,6 @@ error[E0635]: unknown feature `const_default_impls`
 LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
    |                                         ^^^^^^^^^^^^^^^^^^^
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:6:12
-   |
-LL | impl const Default for A {
-   |            ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:10:12
-   |
-LL | impl const PartialEq for A {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:14:16
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:14:25
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                         ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0635`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
index fa78326587c..37d123e4ccc 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
@@ -1,13 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-with-params.rs:6:16
-   |
-LL | #[derive_const(PartialEq)]
-   |                ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/derive-const-with-params.rs:6:16
    |
@@ -16,5 +6,5 @@ LL | #[derive_const(PartialEq)]
    |
    = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
index c936270de26..428286e0b12 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
   --> $DIR/cross-crate.rs:17:14
    |
 LL |     NonConst.func();
-   |              ^^^^^^
+   |              ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`
 
 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/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
index 1f78af79418..95edbdc0efa 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
@@ -1,6 +1,6 @@
 // revisions: stock gated stocknc gatednc
 // [gated] check-pass
-#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))]
+#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))]
 
 // aux-build: cross-crate.rs
 extern crate cross_crate;
@@ -16,7 +16,7 @@ const fn const_context() {
     #[cfg(any(stocknc, gatednc))]
     NonConst.func();
     //[stocknc]~^ ERROR: cannot call
-    //[gatednc]~^^ ERROR: cannot call
+    //[gatednc]~^^ ERROR: the trait bound
     Const.func();
     //[stock]~^ ERROR: cannot call
     //[stocknc]~^^ ERROR: cannot call
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
index c21c73f40f2..a6881b8fed5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `(): Tr` is not satisfied
+error[E0277]: the trait bound `(): ~const Tr` is not satisfied
   --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
    |
 LL |         ().a()
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
index 730e268c091..5a0db816a2b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
@@ -1,5 +1,5 @@
 // check-pass
-#![feature(const_trait_impl, rustc_attrs)]
+#![feature(const_trait_impl, rustc_attrs, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
index 49457354cc9..e7ba0505d9b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
@@ -7,7 +7,7 @@
 
 // ensure we are passing in the correct host effect in always const contexts.
 
-pub const fn hmm</* T, */ #[rustc_host] const host: bool = true>() -> usize {
+pub const fn hmm<T, #[rustc_host] const host: bool = true>() -> usize {
     if host {
         1
     } else {
@@ -16,14 +16,12 @@ pub const fn hmm</* T, */ #[rustc_host] const host: bool = true>() -> usize {
 }
 
 const _: () = {
-    let x = hmm();
+    let x = hmm::<()>();
     assert!(0 == x);
 };
 
-/* FIXME(effects)
 pub const fn uwu(x: [u8; hmm::<()>()]) {
     let [] = x;
 }
-*/
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
index 1b21d7c0e0e..6a177592b64 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
@@ -1,11 +1,16 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/generic-bound.rs:16:15
+error[E0015]: cannot call non-const operator in constant functions
+  --> $DIR/generic-bound.rs:25:5
    |
-LL | impl<T> const std::ops::Add for S<T> {
-   |               ^^^^^^^^^^^^^
+LL |     arg + arg
+   |     ^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/generic-bound.rs:16:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl<T> const std::ops::Add for S<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
index 337c733403b..426534deb67 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
@@ -1,6 +1,6 @@
 // Regression test for #69615.
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait MyTrait {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
index a3bb9b3f93e..9a93d01ed06 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -1,6 +1,6 @@
 // Tests that specializing trait impls must be at least as const as the default impl.
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(min_specialization)]
 
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
index 0a28da9e65e..7206a89e5c5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl, min_specialization, rustc_attrs)]
+#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)]
 
 #[rustc_specialization_trait]
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
index 1d79f5adf93..b3977e6cede 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
@@ -1,7 +1,7 @@
 // revisions: stable unstable
 
 #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file.
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
index 35dc1ca129b..deed05ae179 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
@@ -1,20 +1,29 @@
-error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
-  --> $DIR/trait-default-body-stability.rs:18:12
+error[E0015]: `?` cannot determine the branch of `T` in constant functions
+  --> $DIR/trait-default-body-stability.rs:44:9
    |
-LL | impl const Try for T {
-   |            ^^^
+LL |         T?
+   |         ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/trait-default-body-stability.rs:18:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const Try for T {
+   | ^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
-  --> $DIR/trait-default-body-stability.rs:33:12
+error[E0015]: `?` cannot convert from residual of `T` in constant functions
+  --> $DIR/trait-default-body-stability.rs:44:9
    |
-LL | impl const FromResidual for T {
-   |            ^^^^^^^^^^^^
+LL |         T?
+   |         ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/trait-default-body-stability.rs:33:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const FromResidual for T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
index 29809a2ee56..6e1074035b7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
@@ -1,7 +1,7 @@
 // known-bug: #110395
 // FIXME run-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Bar {
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 6eff899bfbf..621e8576249 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -1,5 +1,5 @@
 #![feature(staged_api)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![stable(feature = "stable", since = "1.0.0")]
 
 #[stable(feature = "stable", since = "1.0.0")]