about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs205
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs20
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs1
-rw-r--r--compiler/rustc_hir/src/intravisit.rs2
-rw-r--r--compiler/rustc_hir/src/lang_items.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs154
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs109
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs44
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs220
-rw-r--r--compiler/rustc_hir_analysis/src/delegation.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs42
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs59
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/explicit.rs3
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs51
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs3
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs14
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs10
-rw-r--r--compiler/rustc_infer/src/infer/context.rs21
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs9
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs74
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs14
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs1
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs3
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/fudge.rs27
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/undo_log.rs5
-rw-r--r--compiler/rustc_lint/src/builtin.rs4
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs15
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs67
-rw-r--r--compiler/rustc_middle/src/query/erase.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs24
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs11
-rw-r--r--compiler/rustc_middle/src/ty/context.rs40
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs3
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs10
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs9
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs89
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs1
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs80
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/predicate.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs10
-rw-r--r--compiler/rustc_middle/src/ty/util.rs46
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/resolve.rs3
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs296
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs3
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs62
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs41
-rw-r--r--compiler/rustc_privacy/src/lib.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs80
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs5
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs1
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs139
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs10
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs22
-rw-r--r--compiler/rustc_type_ir/src/const_kind.rs23
-rw-r--r--compiler/rustc_type_ir/src/effects.rs59
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs75
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs10
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs8
-rw-r--r--compiler/rustc_type_ir/src/interner.rs11
-rw-r--r--compiler/rustc_type_ir/src/ir_print.rs5
-rw-r--r--compiler/rustc_type_ir/src/lang_items.rs7
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs65
-rw-r--r--compiler/rustc_type_ir/src/predicate_kind.rs7
-rw-r--r--compiler/rustc_type_ir/src/relate/combine.rs28
-rw-r--r--compiler/stable_mir/src/ty.rs1
-rw-r--r--library/core/src/marker.rs44
-rw-r--r--src/librustdoc/clean/auto_trait.rs2
-rw-r--r--src/librustdoc/clean/mod.rs10
-rw-r--r--src/librustdoc/clean/types.rs3
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs14
-rw-r--r--tests/crashes/118320.rs14
-rw-r--r--tests/crashes/119924-6.rs15
-rw-r--r--tests/ui/const-generics/issues/issue-88119.stderr18
-rw-r--r--tests/ui/consts/const-block-const-bound.stderr10
-rw-r--r--tests/ui/consts/const-try.rs4
-rw-r--r--tests/ui/consts/const-try.stderr9
-rw-r--r--tests/ui/consts/constifconst-call-in-const-position.stderr20
-rw-r--r--tests/ui/consts/fn_trait_refs.stderr74
-rw-r--r--tests/ui/consts/unstable-const-fn-in-libcore.stderr10
-rw-r--r--tests/ui/delegation/ice-issue-124347.rs2
-rw-r--r--tests/ui/delegation/ice-issue-124347.stderr12
-rw-r--r--tests/ui/delegation/unsupported.rs2
-rw-r--r--tests/ui/delegation/unsupported.stderr12
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr18
-rw-r--r--tests/ui/specialization/const_trait_impl.stderr62
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs1
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr47
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs2
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr45
-rw-r--r--tests/ui/traits/const-traits/assoc-type.rs5
-rw-r--r--tests/ui/traits/const-traits/assoc-type.stderr16
-rw-r--r--tests/ui/traits/const-traits/call-const-closure.rs22
-rw-r--r--tests/ui/traits/const-traits/call-const-closure.stderr9
-rw-r--r--tests/ui/traits/const-traits/call-const-in-tilde-const.rs14
-rw-r--r--tests/ui/traits/const-traits/call-const-in-tilde-const.stderr18
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-fail.stderr15
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.stderr14
-rw-r--r--tests/ui/traits/const-traits/call-generic-in-impl.stderr16
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-chain.rs1
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-chain.stderr31
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-dup-bound.rs1
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr31
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.stderr16
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-pass.rs1
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-pass.stderr19
-rw-r--r--tests/ui/traits/const-traits/const-bound-in-host.rs15
-rw-r--r--tests/ui/traits/const-traits/const-bound-in-host.stderr11
-rw-r--r--tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs2
-rw-r--r--tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr15
-rw-r--r--tests/ui/traits/const-traits/const-bounds-non-const-trait.rs1
-rw-r--r--tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr12
-rw-r--r--tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs2
-rw-r--r--tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr11
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr18
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.stderr18
-rw-r--r--tests/ui/traits/const-traits/const-closures.stderr34
-rw-r--r--tests/ui/traits/const-traits/const-default-method-bodies.stderr17
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.stderr26
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stderr10
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.precise.stderr10
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.stock.stderr10
-rw-r--r--tests/ui/traits/const-traits/const-drop.precise.stderr24
-rw-r--r--tests/ui/traits/const-traits/const-drop.stock.stderr24
-rw-r--r--tests/ui/traits/const-traits/const-fns-are-early-bound.rs50
-rw-r--r--tests/ui/traits/const-traits/const-fns-are-early-bound.stderr20
-rw-r--r--tests/ui/traits/const-traits/const-impl-requires-const-trait.rs7
-rw-r--r--tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr20
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.rs3
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.stderr249
-rw-r--r--tests/ui/traits/const-traits/const-in-closure.rs25
-rw-r--r--tests/ui/traits/const-traits/const-in-closure.stderr11
-rw-r--r--tests/ui/traits/const-traits/cross-crate.gatednc.stderr17
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr17
-rw-r--r--tests/ui/traits/const-traits/dont-observe-host-opaque.rs12
-rw-r--r--tests/ui/traits/const-traits/dont-observe-host-opaque.stderr11
-rw-r--r--tests/ui/traits/const-traits/dont-observe-host.rs23
-rw-r--r--tests/ui/traits/const-traits/dont-observe-host.stderr11
-rw-r--r--tests/ui/traits/const-traits/effects/minicore.rs32
-rw-r--r--tests/ui/traits/const-traits/effects/minicore.stderr8
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr16
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params.rs1
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr30
-rw-r--r--tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs1
-rw-r--r--tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr14
-rw-r--r--tests/ui/traits/const-traits/fn-ptr-lub.rs20
-rw-r--r--tests/ui/traits/const-traits/fn-ptr-lub.stderr11
-rw-r--r--tests/ui/traits/const-traits/hir-const-check.rs2
-rw-r--r--tests/ui/traits/const-traits/hir-const-check.stderr11
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs1
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr10
-rw-r--r--tests/ui/traits/const-traits/issue-92111.stderr10
-rw-r--r--tests/ui/traits/const-traits/item-bound-entailment-fails.rs31
-rw-r--r--tests/ui/traits/const-traits/item-bound-entailment-fails.stderr36
-rw-r--r--tests/ui/traits/const-traits/item-bound-entailment.rs31
-rw-r--r--tests/ui/traits/const-traits/item-bound-entailment.stderr11
-rw-r--r--tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr16
-rw-r--r--tests/ui/traits/const-traits/predicate-entailment-fails.rs43
-rw-r--r--tests/ui/traits/const-traits/predicate-entailment-fails.stderr66
-rw-r--r--tests/ui/traits/const-traits/predicate-entailment-passes.rs39
-rw-r--r--tests/ui/traits/const-traits/predicate-entailment-passes.stderr11
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr32
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr25
-rw-r--r--tests/ui/traits/const-traits/specialization/default-keyword.rs3
-rw-r--r--tests/ui/traits/const-traits/specialization/default-keyword.stderr12
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs3
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr43
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs3
-rw-r--r--tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr43
-rw-r--r--tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr25
-rw-r--r--tests/ui/traits/const-traits/specializing-constness-2.stderr25
-rw-r--r--tests/ui/traits/const-traits/specializing-constness.rs2
-rw-r--r--tests/ui/traits/const-traits/specializing-constness.stderr14
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr18
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.rs4
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr17
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr17
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr12
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr18
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.rs5
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr29
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail.rs1
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail.stderr23
-rw-r--r--tests/ui/traits/const-traits/tilde-const-and-const-params.rs2
-rw-r--r--tests/ui/traits/const-traits/tilde-const-and-const-params.stderr25
-rw-r--r--tests/ui/traits/const-traits/tilde-const-in-struct-args.rs21
-rw-r--r--tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr11
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.rs6
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.stderr51
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr25
221 files changed, 2364 insertions, 2749 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c43106c6e5f..97fa90d340e 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -57,7 +57,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
         owner: NodeId,
         f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>,
     ) {
-        let mut lctx = LoweringContext::new(self.tcx, self.resolver, self.ast_index);
+        let mut lctx = LoweringContext::new(self.tcx, self.resolver);
         lctx.with_hir_id_owner(owner, |lctx| f(lctx));
 
         for (def_id, info) in lctx.children {
@@ -193,8 +193,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
                 let (generics, (ty, body_id)) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
@@ -225,16 +223,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     );
 
                     let itctx = ImplTraitContext::Universal;
-                    let (generics, decl) =
-                        this.lower_generics(generics, header.constness, false, id, itctx, |this| {
-                            this.lower_fn_decl(
-                                decl,
-                                id,
-                                *fn_sig_span,
-                                FnDeclKind::Fn,
-                                coroutine_kind,
-                            )
-                        });
+                    let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {
+                        this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, coroutine_kind)
+                    });
                     let sig = hir::FnSig {
                         decl,
                         header: this.lower_fn_header(*header, hir::Safety::Safe),
@@ -269,8 +260,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 add_ty_alias_where_clause(&mut generics, *where_clauses, true);
                 let (generics, ty) = self.lower_generics(
                     &generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
@@ -294,8 +283,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::Enum(enum_definition, generics) => {
                 let (generics, variants) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
@@ -309,8 +296,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::Struct(struct_def, generics) => {
                 let (generics, struct_def) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, struct_def),
@@ -320,8 +305,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::Union(vdata, generics) => {
                 let (generics, vdata) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, vdata),
@@ -353,7 +336,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 // parent lifetime.
                 let itctx = ImplTraitContext::Universal;
                 let (generics, (trait_ref, lowered_ty)) =
-                    self.lower_generics(ast_generics, Const::No, false, id, itctx, |this| {
+                    self.lower_generics(ast_generics, id, itctx, |this| {
                         let modifiers = TraitBoundModifiers {
                             constness: BoundConstness::Never,
                             asyncness: BoundAsyncness::Normal,
@@ -405,8 +388,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => {
                 let (generics, (safety, items, bounds)) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
@@ -426,8 +407,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::TraitAlias(generics, bounds) => {
                 let (generics, bounds) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
@@ -604,50 +583,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
         ctxt: AssocCtxt,
         parent_hir: &'hir hir::OwnerInfo<'hir>,
     ) -> hir::OwnerNode<'hir> {
-        // Evaluate with the lifetimes in `params` in-scope.
-        // This is used to track which lifetimes have already been defined,
-        // and which need to be replicated when lowering an async fn.
-
         let parent_item = parent_hir.node().expect_item();
-        let constness = match parent_item.kind {
+        match parent_item.kind {
             hir::ItemKind::Impl(impl_) => {
                 self.is_in_trait_impl = impl_.of_trait.is_some();
-                // N.B. the impl should always lower to methods that have `const host: bool` params if the trait
-                // is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
-                // calling non-const impls are done through associated types.
-                if let Some(def_id) = impl_.of_trait.and_then(|tr| tr.trait_def_id()) {
-                    if let Some(local_def) = def_id.as_local() {
-                        match &self.ast_index[local_def] {
-                            AstOwner::Item(ast::Item { attrs, .. }) => attrs
-                                .iter()
-                                .find(|attr| attr.has_name(sym::const_trait))
-                                .map_or(Const::No, |attr| Const::Yes(attr.span)),
-                            _ => Const::No,
-                        }
-                    } else if self.tcx.is_const_trait(def_id) {
-                        // FIXME(effects) span
-                        Const::Yes(self.tcx.def_ident_span(def_id).unwrap())
-                    } else {
-                        Const::No
-                    }
-                } else {
-                    Const::No
-                }
             }
-            hir::ItemKind::Trait(_, _, _, _, _) => parent_hir
-                .attrs
-                .get(parent_item.hir_id().local_id)
-                .iter()
-                .find(|attr| attr.has_name(sym::const_trait))
-                .map_or(Const::No, |attr| Const::Yes(attr.span)),
+            hir::ItemKind::Trait(_, _, _, _, _) => {}
             kind => {
                 span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
             }
-        };
+        }
 
+        // Evaluate with the lifetimes in `params` in-scope.
+        // This is used to track which lifetimes have already been defined,
+        // and which need to be replicated when lowering an async fn.
         match ctxt {
-            AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item, constness)),
-            AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item, constness)),
+            AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
+            AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
         }
     }
 
@@ -663,7 +615,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let fdec = &sig.decl;
                     let itctx = ImplTraitContext::Universal;
                     let (generics, (decl, fn_args)) =
-                        self.lower_generics(generics, Const::No, false, i.id, itctx, |this| {
+                        self.lower_generics(generics, i.id, itctx, |this| {
                             (
                                 // Disallow `impl Trait` in foreign items.
                                 this.lower_fn_decl(
@@ -775,11 +727,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    fn lower_trait_item(
-        &mut self,
-        i: &AssocItem,
-        trait_constness: Const,
-    ) -> &'hir hir::TraitItem<'hir> {
+    fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
         let hir_id = self.lower_node_id(i.id);
         self.lower_attrs(hir_id, &i.attrs);
         let trait_item_def_id = hir_id.expect_owner();
@@ -788,8 +736,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => {
                 let (generics, kind) = self.lower_generics(
                     generics,
-                    Const::No,
-                    false,
                     i.id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
@@ -810,7 +756,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     i.id,
                     FnDeclKind::Trait,
                     sig.header.coroutine_kind,
-                    trait_constness,
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
             }
@@ -829,7 +774,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     i.id,
                     FnDeclKind::Trait,
                     sig.header.coroutine_kind,
-                    trait_constness,
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
             }
@@ -838,8 +782,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
                 let (generics, kind) = self.lower_generics(
                     &generics,
-                    Const::No,
-                    false,
                     i.id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
@@ -912,11 +854,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.expr(span, hir::ExprKind::Err(guar))
     }
 
-    fn lower_impl_item(
-        &mut self,
-        i: &AssocItem,
-        constness_of_trait: Const,
-    ) -> &'hir hir::ImplItem<'hir> {
+    fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
         // Since `default impl` is not yet implemented, this is always true in impls.
         let has_value = true;
         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
@@ -926,8 +864,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let (generics, kind) = match &i.kind {
             AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
                 generics,
-                Const::No,
-                false,
                 i.id,
                 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                 |this| {
@@ -953,7 +889,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     i.id,
                     if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
                     sig.header.coroutine_kind,
-                    constness_of_trait,
                 );
 
                 (generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -963,8 +898,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
                 self.lower_generics(
                     &generics,
-                    Const::No,
-                    false,
                     i.id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
@@ -1370,18 +1303,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
         id: NodeId,
         kind: FnDeclKind,
         coroutine_kind: Option<CoroutineKind>,
-        parent_constness: Const,
     ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
         let header = self.lower_fn_header(sig.header, hir::Safety::Safe);
-        // Don't pass along the user-provided constness of trait associated functions; we don't want to
-        // synthesize a host effect param for them. We reject `const` on them during AST validation.
-        let constness =
-            if kind == FnDeclKind::Inherent { sig.header.constness } else { parent_constness };
         let itctx = ImplTraitContext::Universal;
-        let (generics, decl) =
-            self.lower_generics(generics, constness, kind == FnDeclKind::Impl, id, itctx, |this| {
-                this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
-            });
+        let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
+            this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
+        });
         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
     }
 
@@ -1460,8 +1387,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_generics<T>(
         &mut self,
         generics: &Generics,
-        constness: Const,
-        force_append_constness: bool,
         parent_node_id: NodeId,
         itctx: ImplTraitContext,
         f: impl FnOnce(&mut Self) -> T,
@@ -1524,30 +1449,6 @@ 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
-            // if this comes from implementing a `const` trait, we must force constness to be appended
-            // to the impl item, no matter whether effects is enabled.
-            && (self.tcx.features().effects() || force_append_constness)
-        {
-            let span = self.lower_span(span);
-            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,
-                sym::host,
-                DefKind::ConstParam,
-                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(
@@ -1595,74 +1496,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
         predicates.extend(impl_trait_bounds.into_iter());
 
-        if let Some((span, hir_id, def_id)) = host_param_parts {
-            let const_node_id = self.next_node_id();
-            let anon_const_did =
-                self.create_def(def_id, const_node_id, kw::Empty, DefKind::AnonConst, span);
-
-            let const_id = self.next_id();
-            let const_expr_id = self.next_id();
-            let bool_id = self.next_id();
-
-            self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
-            self.children.push((anon_const_did, hir::MaybeOwner::NonOwner(const_id)));
-
-            let const_body = self.lower_body(|this| {
-                (&[], hir::Expr {
-                    hir_id: const_expr_id,
-                    kind: hir::ExprKind::Lit(
-                        this.arena.alloc(hir::Lit { node: LitKind::Bool(true), span }),
-                    ),
-                    span,
-                })
-            });
-
-            let default_ac = self.arena.alloc(hir::AnonConst {
-                def_id: anon_const_did,
-                hir_id: const_id,
-                body: const_body,
-                span,
-            });
-            let default_ct = self.arena.alloc(hir::ConstArg {
-                hir_id: self.next_id(),
-                kind: hir::ConstArgKind::Anon(default_ac),
-                is_desugared_from_effects: false,
-            });
-            let param = hir::GenericParam {
-                def_id,
-                hir_id,
-                name: hir::ParamName::Plain(Ident { name: sym::host, span }),
-                span,
-                kind: hir::GenericParamKind::Const {
-                    ty: self.arena.alloc(self.ty(
-                        span,
-                        hir::TyKind::Path(hir::QPath::Resolved(
-                            None,
-                            self.arena.alloc(hir::Path {
-                                res: Res::PrimTy(hir::PrimTy::Bool),
-                                span,
-                                segments: self.arena.alloc_from_iter([hir::PathSegment {
-                                    ident: Ident { name: sym::bool, span },
-                                    hir_id: bool_id,
-                                    res: Res::PrimTy(hir::PrimTy::Bool),
-                                    args: None,
-                                    infer_args: false,
-                                }]),
-                            }),
-                        )),
-                    )),
-                    default: Some(default_ct),
-                    is_host_effect: true,
-                    synthetic: true,
-                },
-                colon_span: None,
-                pure_wrt_drop: false,
-                source: hir::GenericParamSource::Generics,
-            };
-
-            params.push(param);
-        }
-
         let lowered_generics = self.arena.alloc(hir::Generics {
             params: self.arena.alloc_from_iter(params),
             predicates: self.arena.alloc_from_iter(predicates),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 7cd0cd1ebcd..34b8137aea8 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -154,17 +154,10 @@ 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<LocalDefIdMap<LocalDefId>>,
-
-    host_param_id: Option<LocalDefId>,
-    ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>,
 }
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
-    fn new(
-        tcx: TyCtxt<'hir>,
-        resolver: &'a mut ResolverAstLowering,
-        ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>,
-    ) -> Self {
+    fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
         Self {
             // Pseudo-globals.
             tcx,
@@ -204,8 +197,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             // interact with `gen`/`async gen` blocks
             allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
             generics_def_id_map: Default::default(),
-            host_param_id: None,
-            ast_index,
         }
     }
 
@@ -2054,11 +2045,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         param: &GenericParam,
         source: hir::GenericParamSource,
     ) -> hir::GenericParam<'hir> {
-        let (name, kind) = self.lower_generic_param_kind(
-            param,
-            source,
-            attr::contains_name(&param.attrs, sym::rustc_runtime),
-        );
+        let (name, kind) = self.lower_generic_param_kind(param, source);
 
         let hir_id = self.lower_node_id(param.id);
         self.lower_attrs(hir_id, &param.attrs);
@@ -2078,7 +2065,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         param: &GenericParam,
         source: hir::GenericParamSource,
-        is_host_effect: bool,
     ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
         match &param.kind {
             GenericParamKind::Lifetime => {
@@ -2144,7 +2130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                 (
                     hir::ParamName::Plain(self.lower_ident(param.ident)),
-                    hir::GenericParamKind::Const { ty, default, is_host_effect, synthetic: false },
+                    hir::GenericParamKind::Const { ty, default, synthetic: false },
                 )
             }
         }
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 753195bf691..5921fbc0fd7 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -838,10 +838,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_const_panic_str, Normal, template!(Word), WarnFollowing,
         EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
     ),
-    rustc_attr!(
-        rustc_runtime, Normal, template!(Word), WarnFollowing,
-        EncodeCrossCrate::No, INTERNAL_UNSTABLE
-    ),
 
     // ==========================================================================
     // Internal attributes, Layout related:
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 45be04c6db9..1c268c8bbe0 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -580,7 +580,6 @@ pub enum GenericParamKind<'hir> {
         ty: &'hir Ty<'hir>,
         /// Optional default value for the const generic param
         default: Option<&'hir ConstArg<'hir>>,
-        is_host_effect: bool,
         synthetic: bool,
     },
 }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index ffe519b0e7d..322f8e2a517 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -935,7 +935,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(
     match param.kind {
         GenericParamKind::Lifetime { .. } => {}
         GenericParamKind::Type { ref default, .. } => visit_opt!(visitor, visit_ty, default),
-        GenericParamKind::Const { ref ty, ref default, is_host_effect: _, synthetic: _ } => {
+        GenericParamKind::Const { ref ty, ref default, synthetic: _ } => {
             try_visit!(visitor.visit_ty(ty));
             if let Some(ref default) = default {
                 try_visit!(visitor.visit_const_param_default(param.hir_id, default));
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index ae046c09ebe..7d81f977c22 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -415,14 +415,6 @@ language_item_table! {
 
     String,                  sym::String,              string,                     Target::Struct,         GenericRequirement::None;
     CStr,                    sym::CStr,                c_str,                      Target::Struct,         GenericRequirement::None;
-
-    EffectsRuntime,          sym::EffectsRuntime,      effects_runtime,            Target::Struct,         GenericRequirement::None;
-    EffectsNoRuntime,        sym::EffectsNoRuntime,    effects_no_runtime,         Target::Struct,         GenericRequirement::None;
-    EffectsMaybe,            sym::EffectsMaybe,        effects_maybe,              Target::Struct,         GenericRequirement::None;
-    EffectsIntersection,     sym::EffectsIntersection, effects_intersection,       Target::Trait,          GenericRequirement::None;
-    EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None;
-    EffectsCompat,           sym::EffectsCompat,       effects_compat,             Target::Trait,          GenericRequirement::Exact(1);
-    EffectsTyCompat,         sym::EffectsTyCompat,     effects_ty_compat,          Target::Trait,          GenericRequirement::Exact(1);
 }
 
 pub enum GenericRequirement {
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index 77df0cb7ef9..1121ca53240 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -3,13 +3,8 @@
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::LangItem;
-use rustc_hir::def::DefKind;
-use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
 use rustc_span::Span;
-use rustc_span::def_id::DefId;
-
-use crate::hir_ty_lowering::PredicateFilter;
 
 /// Collects together a list of type bounds. These lists of bounds occur in many places
 /// in Rust's syntax:
@@ -47,12 +42,9 @@ impl<'tcx> Bounds<'tcx> {
     pub(crate) fn push_trait_bound(
         &mut self,
         tcx: TyCtxt<'tcx>,
-        defining_def_id: DefId,
         bound_trait_ref: ty::PolyTraitRef<'tcx>,
         span: Span,
         polarity: ty::PredicatePolarity,
-        constness: Option<ty::BoundConstness>,
-        predicate_filter: PredicateFilter,
     ) {
         let clause = (
             bound_trait_ref
@@ -68,137 +60,6 @@ impl<'tcx> Bounds<'tcx> {
         } else {
             self.clauses.push(clause);
         }
-
-        // FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else.
-        // Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated
-        // type bounds.
-        if !tcx.features().effects() {
-            return;
-        }
-        match predicate_filter {
-            PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
-                return;
-            }
-            PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
-                // Ok.
-            }
-        }
-
-        // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the
-        // associated type of `<T as Tr>` and make sure that the effect is compatible.
-        let compat_val = match (tcx.def_kind(defining_def_id), constness) {
-            // FIXME(effects): revisit the correctness of this
-            (_, Some(ty::BoundConstness::Const)) => tcx.consts.false_,
-            // body owners that can have trait bounds
-            (
-                DefKind::Const | DefKind::Fn | DefKind::AssocFn,
-                Some(ty::BoundConstness::ConstIfConst),
-            ) => tcx.expected_host_effect_param_for_body(defining_def_id),
-
-            (_, None) => {
-                if !tcx.is_const_trait(bound_trait_ref.def_id()) {
-                    return;
-                }
-                tcx.consts.true_
-            }
-            (DefKind::Trait, Some(ty::BoundConstness::ConstIfConst)) => {
-                // we are in a trait, where `bound_trait_ref` could be:
-                // (1) a super trait `trait Foo: ~const Bar`.
-                //     - This generates `<Self as Foo>::Effects: TyCompat<<Self as Bar>::Effects>`
-                //
-                // (2) a where clause `where for<..> Something: ~const Bar`.
-                //     - This generates `for<..> <Self as Foo>::Effects: TyCompat<<Something as Bar>::Effects>`
-                let Some(own_fx) = tcx.associated_type_for_effects(defining_def_id) else {
-                    tcx.dcx().span_delayed_bug(span, "should not have allowed `~const` on a trait that doesn't have `#[const_trait]`");
-                    return;
-                };
-                let own_fx_ty = Ty::new_projection(
-                    tcx,
-                    own_fx,
-                    ty::GenericArgs::identity_for_item(tcx, own_fx),
-                );
-                let Some(their_fx) = tcx.associated_type_for_effects(bound_trait_ref.def_id())
-                else {
-                    tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
-                    return;
-                };
-                let their_fx_ty =
-                    Ty::new_projection(tcx, their_fx, bound_trait_ref.skip_binder().args);
-                let compat = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span));
-                let clause = bound_trait_ref
-                    .map_bound(|_| {
-                        let trait_ref = ty::TraitRef::new(tcx, compat, [own_fx_ty, their_fx_ty]);
-                        ty::ClauseKind::Trait(ty::TraitPredicate {
-                            trait_ref,
-                            polarity: ty::PredicatePolarity::Positive,
-                        })
-                    })
-                    .upcast(tcx);
-
-                self.clauses.push((clause, span));
-                return;
-            }
-
-            (DefKind::Impl { of_trait: true }, Some(ty::BoundConstness::ConstIfConst)) => {
-                // this is a where clause on an impl header.
-                // push `<T as Tr>::Effects` into the set for the `Min` bound.
-                let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
-                    tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
-                    return;
-                };
-
-                let ty = bound_trait_ref
-                    .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args));
-
-                // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the
-                // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in
-                // the `Min` associated type properly (which doesn't allow using `for<>`)
-                // This should work for any bound variables as long as they don't have any
-                // bounds e.g. `for<T: Trait>`.
-                // FIXME(effects) reconsider this approach to allow compatibility with `for<T: Tr>`
-                let ty = tcx.replace_bound_vars_uncached(ty, FnMutDelegate {
-                    regions: &mut |_| tcx.lifetimes.re_static,
-                    types: &mut |_| tcx.types.unit,
-                    consts: &mut |_| unimplemented!("`~const` does not support const binders"),
-                });
-
-                self.effects_min_tys.insert(ty, span);
-                return;
-            }
-            // for
-            // ```
-            // trait Foo { type Bar: ~const Trait }
-            // ```
-            // ensure that `<Self::Bar as Trait>::Effects: TyCompat<Self::Effects>`.
-            //
-            // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor
-            // that uses a `Bar` that implements `Trait` with `Maybe` effects.
-            (DefKind::AssocTy, Some(ty::BoundConstness::ConstIfConst)) => {
-                // FIXME(effects): implement this
-                return;
-            }
-            // probably illegal in this position.
-            (_, Some(ty::BoundConstness::ConstIfConst)) => {
-                tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered");
-                return;
-            }
-        };
-        // create a new projection type `<T as Tr>::Effects`
-        let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
-            tcx.dcx().span_delayed_bug(
-                span,
-                "`~const` trait bound has no effect assoc yet no errors encountered?",
-            );
-            return;
-        };
-        let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args);
-        // make `<T as Tr>::Effects: Compat<runtime>`
-        let new_trait_ref =
-            ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), [
-                ty::GenericArg::from(self_ty),
-                compat_val.into(),
-            ]);
-        self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span));
     }
 
     pub(crate) fn push_projection_bound(
@@ -220,6 +81,21 @@ impl<'tcx> Bounds<'tcx> {
         self.clauses.insert(0, (trait_ref.upcast(tcx), span));
     }
 
+    /// Push a `const` or `~const` bound as a `HostEffect` predicate.
+    pub(crate) fn push_const_bound(
+        &mut self,
+        tcx: TyCtxt<'tcx>,
+        bound_trait_ref: ty::PolyTraitRef<'tcx>,
+        host: ty::HostPolarity,
+        span: Span,
+    ) {
+        if tcx.is_const_trait(bound_trait_ref.def_id()) {
+            self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, host), span));
+        } else {
+            tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait");
+        }
+    }
+
     pub(crate) fn clauses(
         &self,
         // FIXME(effects): remove tcx
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 7a56b3784f8..02cf1a502f1 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -181,6 +181,7 @@ fn compare_method_predicate_entailment<'tcx>(
         });
 
     // Create mapping from trait method to impl method.
+    let impl_def_id = impl_m.container_id(tcx);
     let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
         tcx,
         impl_m.container_id(tcx),
@@ -204,6 +205,24 @@ fn compare_method_predicate_entailment<'tcx>(
         trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
     );
 
+    // FIXME(effects): This should be replaced with a more dedicated method.
+    let is_conditionally_const = tcx.is_conditionally_const(impl_def_id);
+    if is_conditionally_const {
+        // Augment the hybrid param-env with the const conditions
+        // of the impl header and the trait method.
+        hybrid_preds.extend(
+            tcx.const_conditions(impl_def_id)
+                .instantiate_identity(tcx)
+                .into_iter()
+                .chain(
+                    tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args),
+                )
+                .map(|(trait_ref, _)| {
+                    trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)
+                }),
+        );
+    }
+
     let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
     let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
     let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
@@ -230,6 +249,34 @@ fn compare_method_predicate_entailment<'tcx>(
         ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
     }
 
+    // If we're within a const implementation, we need to make sure that the method
+    // does not assume stronger `~const` bounds than the trait definition.
+    //
+    // This registers the `~const` bounds of the impl method, which we will prove
+    // using the hybrid param-env that we earlier augmented with the const conditions
+    // from the impl header and trait method declaration.
+    if is_conditionally_const {
+        for (const_condition, span) in
+            tcx.const_conditions(impl_m.def_id).instantiate_own_identity()
+        {
+            let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
+            let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
+
+            let cause =
+                ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
+                    impl_item_def_id: impl_m_def_id,
+                    trait_item_def_id: trait_m.def_id,
+                    kind: impl_m.kind,
+                });
+            ocx.register_obligation(traits::Obligation::new(
+                tcx,
+                cause,
+                param_env,
+                const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
+            ));
+        }
+    }
+
     // We now need to check that the signature of the impl method is
     // compatible with that of the trait method. We do this by
     // checking that `impl_fty <: trait_fty`.
@@ -1846,9 +1893,10 @@ fn compare_type_predicate_entailment<'tcx>(
     trait_ty: ty::AssocItem,
     impl_trait_ref: ty::TraitRef<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
+    let impl_def_id = impl_ty.container_id(tcx);
     let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto(
         tcx,
-        impl_ty.container_id(tcx),
+        impl_def_id,
         impl_trait_ref.args,
     );
 
@@ -1856,6 +1904,7 @@ fn compare_type_predicate_entailment<'tcx>(
     let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
 
     let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity();
+    // If there are no bounds, then there are no const conditions, so no need to check that here.
     if impl_ty_own_bounds.len() == 0 {
         // Nothing to check.
         return Ok(());
@@ -1881,6 +1930,23 @@ fn compare_type_predicate_entailment<'tcx>(
     let impl_ty_span = tcx.def_span(impl_ty_def_id);
     let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id);
 
+    let is_conditionally_const = tcx.is_conditionally_const(impl_ty.def_id);
+    if is_conditionally_const {
+        // Augment the hybrid param-env with the const conditions
+        // of the impl header and the trait assoc type.
+        hybrid_preds.extend(
+            tcx.const_conditions(impl_ty_predicates.parent.unwrap())
+                .instantiate_identity(tcx)
+                .into_iter()
+                .chain(
+                    tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args),
+                )
+                .map(|(trait_ref, _)| {
+                    trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)
+                }),
+        );
+    }
+
     let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
     let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
     debug!(caller_bounds=?param_env.caller_bounds());
@@ -1901,6 +1967,29 @@ fn compare_type_predicate_entailment<'tcx>(
         ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
     }
 
+    if is_conditionally_const {
+        // Validate the const conditions of the impl associated type.
+        let impl_ty_own_const_conditions =
+            tcx.const_conditions(impl_ty.def_id).instantiate_own_identity();
+        for (const_condition, span) in impl_ty_own_const_conditions {
+            let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id);
+            let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
+
+            let cause =
+                ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem {
+                    impl_item_def_id: impl_ty_def_id,
+                    trait_item_def_id: trait_ty.def_id,
+                    kind: impl_ty.kind,
+                });
+            ocx.register_obligation(traits::Obligation::new(
+                tcx,
+                cause,
+                param_env,
+                const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
+            ));
+        }
+    }
+
     // Check that all obligations are satisfied by the implementation's
     // version.
     let errors = ocx.select_all_or_error();
@@ -1983,7 +2072,7 @@ pub(super) fn check_type_bounds<'tcx>(
         ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
     };
 
-    let obligations: Vec<_> = tcx
+    let mut obligations: Vec<_> = tcx
         .explicit_item_bounds(trait_ty.def_id)
         .iter_instantiated_copied(tcx, rebased_args)
         .map(|(concrete_ty_bound, span)| {
@@ -1991,6 +2080,22 @@ pub(super) fn check_type_bounds<'tcx>(
             traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
         })
         .collect();
+
+    // Only in a const implementation do we need to check that the `~const` item bounds hold.
+    if tcx.is_conditionally_const(impl_ty_def_id) {
+        obligations.extend(
+            tcx.implied_const_bounds(trait_ty.def_id)
+                .iter_instantiated_copied(tcx, rebased_args)
+                .map(|(c, span)| {
+                    traits::Obligation::new(
+                        tcx,
+                        mk_cause(span),
+                        param_env,
+                        c.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
+                    )
+                }),
+        );
+    }
     debug!(item_bounds=?obligations);
 
     // Normalize predicates with the assumption that the GAT may always normalize
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 06317a3b304..c75bdcec388 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -58,15 +58,9 @@ fn equate_intrinsic_type<'tcx>(
 
     // the host effect param should be invisible as it shouldn't matter
     // whether effects is enabled for the intrinsic provider crate.
-    let consts_count = if generics.host_effect_index.is_some() {
-        own_counts.consts - 1
-    } else {
-        own_counts.consts
-    };
-
     if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime")
         && gen_count_ok(own_counts.types, n_tps, "type")
-        && gen_count_ok(consts_count, n_cts, "const")
+        && gen_count_ok(own_counts.consts, n_cts, "const")
     {
         let _ = check_function_signature(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index d70e8673c52..499e42d31c9 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -32,7 +32,8 @@ use rustc_trait_selection::traits::misc::{
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
-    self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
+    self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
+    WellFormedLoc,
 };
 use rustc_type_ir::TypeFlags;
 use rustc_type_ir::solve::NoSolution;
@@ -86,7 +87,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
             self.body_def_id,
             ObligationCauseCode::WellFormed(loc),
         );
-        self.ocx.register_obligation(traits::Obligation::new(
+        self.ocx.register_obligation(Obligation::new(
             self.tcx(),
             cause,
             self.param_env,
@@ -913,12 +914,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
         hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()),
 
         // Const parameters are well formed if their type is structural match.
-        hir::GenericParamKind::Const {
-            ty: hir_ty,
-            default: _,
-            is_host_effect: _,
-            synthetic: _,
-        } => {
+        hir::GenericParamKind::Const { ty: hir_ty, default: _, synthetic: _ } => {
             let ty = tcx.type_of(param.def_id).instantiate_identity();
 
             if tcx.features().unsized_const_params() {
@@ -1178,7 +1174,7 @@ fn check_type_defn<'tcx>(
                     wfcx.body_def_id,
                     ObligationCauseCode::Misc,
                 );
-                wfcx.register_obligation(traits::Obligation::new(
+                wfcx.register_obligation(Obligation::new(
                     tcx,
                     cause,
                     wfcx.param_env,
@@ -1374,6 +1370,30 @@ fn check_impl<'tcx>(
                         obligation.cause.span = hir_self_ty.span;
                     }
                 }
+
+                // Ensure that the `~const` where clauses of the trait hold for the impl.
+                if tcx.is_conditionally_const(item.owner_id.def_id) {
+                    for (bound, _) in
+                        tcx.const_conditions(trait_ref.def_id).instantiate(tcx, trait_ref.args)
+                    {
+                        let bound = wfcx.normalize(
+                            item.span,
+                            Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
+                            bound,
+                        );
+                        wfcx.register_obligation(Obligation::new(
+                            tcx,
+                            ObligationCause::new(
+                                hir_self_ty.span,
+                                wfcx.body_def_id,
+                                ObligationCauseCode::WellFormed(None),
+                            ),
+                            wfcx.param_env,
+                            bound.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
+                        ))
+                    }
+                }
+
                 debug!(?obligations);
                 wfcx.register_obligations(obligations);
             }
@@ -1566,7 +1586,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
                 wfcx.body_def_id,
                 ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP),
             );
-            traits::Obligation::new(tcx, cause, wfcx.param_env, pred)
+            Obligation::new(tcx, cause, wfcx.param_env, pred)
         });
 
     let predicates = predicates.instantiate_identity(tcx);
@@ -1857,7 +1877,7 @@ fn receiver_is_implemented<'tcx>(
     let tcx = wfcx.tcx();
     let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]);
 
-    let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref);
+    let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref);
 
     if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) {
         true
@@ -2193,7 +2213,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
                         .unwrap_or(obligation_span);
                 }
 
-                let obligation = traits::Obligation::new(
+                let obligation = Obligation::new(
                     tcx,
                     traits::ObligationCause::new(
                         span,
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index acc21d0994b..f46b7a8bc9c 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -77,6 +77,8 @@ pub fn provide(providers: &mut Providers) {
         explicit_supertraits_containing_assoc_item:
             predicates_of::explicit_supertraits_containing_assoc_item,
         trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
+        const_conditions: predicates_of::const_conditions,
+        implied_const_bounds: predicates_of::implied_const_bounds,
         type_param_predicates: predicates_of::type_param_predicates,
         trait_def,
         adt_def,
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 348b2260d26..3eec0e12665 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -53,7 +53,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
             param_def_id_to_index,
             has_self: opaque_ty_generics.has_self,
             has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
-            host_effect_index: parent_generics.host_effect_index,
         };
     }
 
@@ -161,7 +160,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                         param_def_id_to_index,
                         has_self: generics.has_self,
                         has_late_bound_regions: generics.has_late_bound_regions,
-                        host_effect_index: None,
                     };
                 } else {
                     // HACK(eddyb) this provides the correct generics when
@@ -292,12 +290,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
     let has_self = opt_self.is_some();
     let mut parent_has_self = false;
     let mut own_start = has_self as u32;
-    let mut host_effect_index = None;
     let parent_count = parent_def_id.map_or(0, |def_id| {
         let generics = tcx.generics_of(def_id);
         assert!(!has_self);
         parent_has_self = generics.has_self;
-        host_effect_index = generics.host_effect_index;
         own_start = generics.count() as u32;
         generics.parent_count + generics.own_params.len()
     });
@@ -361,12 +357,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 kind,
             })
         }
-        GenericParamKind::Const { ty: _, default, is_host_effect, synthetic } => {
-            if !matches!(allow_defaults, Defaults::Allowed)
-                && default.is_some()
-                // `host` effect params are allowed to have defaults.
-                && !is_host_effect
-            {
+        GenericParamKind::Const { ty: _, default, synthetic } => {
+            if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() {
                 tcx.dcx().span_err(
                     param.span,
                     "defaults for const parameters are only allowed in \
@@ -376,27 +368,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
 
             let index = next_index();
 
-            if is_host_effect {
-                if let Some(idx) = host_effect_index {
-                    tcx.dcx().span_delayed_bug(
-                        param.span,
-                        format!("parent also has host effect param? index: {idx}, def: {def_id:?}"),
-                    );
-                }
-
-                host_effect_index = Some(index as usize);
-            }
-
             Some(ty::GenericParamDef {
                 index,
                 name: param.name.ident().name,
                 def_id: param.def_id.to_def_id(),
                 pure_wrt_drop: param.pure_wrt_drop,
-                kind: ty::GenericParamDefKind::Const {
-                    has_default: default.is_some(),
-                    is_host_effect,
-                    synthetic,
-                },
+                kind: ty::GenericParamDefKind::Const { has_default: default.is_some(), synthetic },
             })
         }
     }));
@@ -459,7 +436,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
         param_def_id_to_index,
         has_self: has_self || parent_has_self,
         has_late_bound_regions: has_late_bound_regions(tcx, node),
-        host_effect_index,
     }
 }
 
@@ -540,8 +516,7 @@ impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
     type Result = ControlFlow<()>;
 
     fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) -> Self::Result {
-        if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind
-        {
+        if let GenericParamKind::Const { ty, default: _, synthetic: _ } = p.kind {
             let prev = self.in_param_ty;
             self.in_param_ty = true;
             let res = self.visit_ty(ty);
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 69ebd3a928a..075faea3d2a 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -40,7 +40,16 @@ fn associated_type_bounds<'tcx>(
     let mut bounds = Bounds::default();
     icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
     // Associated types are implicitly sized unless a `?Sized` bound is found
-    icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
+    match filter {
+        PredicateFilter::All
+        | PredicateFilter::SelfOnly
+        | PredicateFilter::SelfThatDefines(_)
+        | PredicateFilter::SelfAndAssociatedTypeBounds => {
+            icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
+        }
+        // `ConstIfConst` is only interested in `~const` bounds.
+        PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
+    }
 
     let trait_def_id = tcx.local_parent(assoc_item_def_id);
     let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
@@ -109,10 +118,19 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
             } else {
                 // Only collect *self* type bounds if the filter is for self.
                 match filter {
-                    PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
+                    PredicateFilter::All => {}
+                    PredicateFilter::SelfOnly => {
                         return None;
                     }
-                    PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {}
+                    PredicateFilter::SelfThatDefines(_)
+                    | PredicateFilter::SelfConstIfConst
+                    | PredicateFilter::SelfAndAssociatedTypeBounds
+                    | PredicateFilter::ConstIfConst => {
+                        unreachable!(
+                            "invalid predicate filter for \
+                            `remap_gat_vars_and_recurse_into_nested_projections`"
+                        )
+                    }
                 }
 
                 clause_ty = alias_ty.self_ty();
@@ -308,7 +326,17 @@ fn opaque_type_bounds<'tcx>(
         let mut bounds = Bounds::default();
         icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
         // Opaque types are implicitly sized unless a `?Sized` bound is found
-        icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
+        match filter {
+            PredicateFilter::All
+            | PredicateFilter::SelfOnly
+            | PredicateFilter::SelfThatDefines(_)
+            | PredicateFilter::SelfAndAssociatedTypeBounds => {
+                // Associated types are implicitly sized unless a `?Sized` bound is found
+                icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
+            }
+            //`ConstIfConst` is only interested in `~const` bounds.
+            PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
+        }
         debug!(?bounds);
 
         tcx.arena.alloc_from_iter(bounds.clauses(tcx))
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 097a1fbc393..61dc4b1677c 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -12,6 +12,7 @@ use rustc_span::symbol::Ident;
 use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument, trace};
 
+use super::item_bounds::explicit_item_bounds_with_filter;
 use crate::bounds::Bounds;
 use crate::collect::ItemCtxt;
 use crate::constrained_generic_params as cgp;
@@ -78,7 +79,6 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
 #[instrument(level = "trace", skip(tcx), ret)]
 fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> {
     use rustc_hir::*;
-    use rustc_middle::ty::Ty;
 
     match tcx.opt_rpitit_info(def_id.to_def_id()) {
         Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => {
@@ -345,26 +345,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
         debug!(?predicates);
     }
 
-    // add `Self::Effects: Compat<HOST>` to ensure non-const impls don't get called
-    // in const contexts.
-    if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(..), .. }) = node
-        && let Some(host_effect_index) = generics.host_effect_index
-    {
-        let parent = generics.parent.unwrap();
-        let Some(assoc_def_id) = tcx.associated_type_for_effects(parent) else {
-            bug!("associated_type_for_effects returned None when there is host effect in generics");
-        };
-        let effects =
-            Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent));
-        let param = generics.param_at(host_effect_index, tcx);
-        let span = tcx.def_span(param.def_id);
-        let host = ty::Const::new_param(tcx, ty::ParamConst::for_def(param));
-        let compat = tcx.require_lang_item(LangItem::EffectsCompat, Some(span));
-        let trait_ref =
-            ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]);
-        predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span));
-    }
-
     ty::GenericPredicates {
         parent: generics.parent,
         predicates: tcx.arena.alloc_from_iter(predicates),
@@ -706,29 +686,76 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
                         assert_eq!(
                             trait_predicate.self_ty(),
                             ty,
-                            "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                            "expected `Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
                         );
                     }
                     ty::ClauseKind::Projection(projection_predicate) => {
                         assert_eq!(
                             projection_predicate.self_ty(),
                             ty,
-                            "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                            "expected `Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
                         );
                     }
                     ty::ClauseKind::TypeOutlives(outlives_predicate) => {
                         assert_eq!(
                             outlives_predicate.0, ty,
-                            "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                            "expected `Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
                         );
                     }
 
                     ty::ClauseKind::RegionOutlives(_)
                     | ty::ClauseKind::ConstArgHasType(_, _)
                     | ty::ClauseKind::WellFormed(_)
-                    | ty::ClauseKind::ConstEvaluatable(_) => {
+                    | ty::ClauseKind::ConstEvaluatable(_)
+                    | ty::ClauseKind::HostEffect(..) => {
+                        bug!(
+                            "unexpected non-`Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                }
+            }
+        }
+        PredicateFilter::ConstIfConst => {
+            for (clause, _) in bounds {
+                match clause.kind().skip_binder() {
+                    ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
+                        trait_ref: _,
+                        host: ty::HostPolarity::Maybe,
+                    }) => {}
+                    _ => {
+                        bug!(
+                            "unexpected non-`HostEffect` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                }
+            }
+        }
+        PredicateFilter::SelfConstIfConst => {
+            for (clause, _) in bounds {
+                match clause.kind().skip_binder() {
+                    ty::ClauseKind::HostEffect(pred) => {
+                        assert_eq!(
+                            pred.host,
+                            ty::HostPolarity::Maybe,
+                            "expected `~const` predicate when computing `{filter:?}` \
+                            implied bounds: {clause:?}",
+                        );
+                        assert_eq!(
+                            pred.trait_ref.self_ty(),
+                            ty,
+                            "expected `Self` predicate when computing `{filter:?}` \
+                            implied bounds: {clause:?}"
+                        );
+                    }
+                    _ => {
                         bug!(
-                            "unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
+                            "unexpected non-`HostEffect` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
                         );
                     }
                 }
@@ -850,3 +877,144 @@ impl<'tcx> ItemCtxt<'tcx> {
         bounds.clauses(self.tcx).collect()
     }
 }
+
+/// Compute the conditions that need to hold for a conditionally-const item to be const.
+/// That is, compute the set of `~const` where clauses for a given item.
+///
+/// This query also computes the `~const` where clauses for associated types, which are
+/// not "const", but which have item bounds which may be `~const`. These must hold for
+/// the `~const` item bound to hold.
+pub(super) fn const_conditions<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> ty::ConstConditions<'tcx> {
+    if !tcx.is_conditionally_const(def_id) {
+        bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
+    }
+
+    let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id)
+    {
+        Node::Item(item) => match item.kind {
+            hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
+            hir::ItemKind::Fn(_, generics, _) => (generics, None, false),
+            hir::ItemKind::Trait(_, _, generics, supertraits, _) => {
+                (generics, Some((item.owner_id.def_id, supertraits)), false)
+            }
+            _ => bug!("const_conditions called on wrong item: {def_id:?}"),
+        },
+        // While associated types are not really const, we do allow them to have `~const`
+        // bounds and where clauses. `const_conditions` is responsible for gathering
+        // these up so we can check them in `compare_type_predicate_entailment`, and
+        // in `HostEffect` goal computation.
+        Node::TraitItem(item) => match item.kind {
+            hir::TraitItemKind::Fn(_, _) | hir::TraitItemKind::Type(_, _) => {
+                (item.generics, None, true)
+            }
+            _ => bug!("const_conditions called on wrong item: {def_id:?}"),
+        },
+        Node::ImplItem(item) => match item.kind {
+            hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => {
+                (item.generics, None, tcx.is_conditionally_const(tcx.local_parent(def_id)))
+            }
+            _ => bug!("const_conditions called on wrong item: {def_id:?}"),
+        },
+        Node::ForeignItem(item) => match item.kind {
+            hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
+            _ => bug!("const_conditions called on wrong item: {def_id:?}"),
+        },
+        // N.B. Tuple ctors are unconditionally constant.
+        Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
+        _ => bug!("const_conditions called on wrong item: {def_id:?}"),
+    };
+
+    let icx = ItemCtxt::new(tcx, def_id);
+    let mut bounds = Bounds::default();
+
+    for pred in generics.predicates {
+        match pred {
+            hir::WherePredicate::BoundPredicate(bound_pred) => {
+                let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
+                let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
+                icx.lowerer().lower_bounds(
+                    ty,
+                    bound_pred.bounds.iter(),
+                    &mut bounds,
+                    bound_vars,
+                    PredicateFilter::ConstIfConst,
+                );
+            }
+            _ => {}
+        }
+    }
+
+    if let Some((def_id, supertraits)) = trait_def_id_and_supertraits {
+        bounds.push_const_bound(
+            tcx,
+            ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())),
+            ty::HostPolarity::Maybe,
+            DUMMY_SP,
+        );
+
+        icx.lowerer().lower_bounds(
+            tcx.types.self_param,
+            supertraits.into_iter(),
+            &mut bounds,
+            ty::List::empty(),
+            PredicateFilter::ConstIfConst,
+        );
+    }
+
+    ty::ConstConditions {
+        parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()),
+        predicates: tcx.arena.alloc_from_iter(bounds.clauses(tcx).map(|(clause, span)| {
+            (
+                clause.kind().map_bound(|clause| match clause {
+                    ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
+                        trait_ref,
+                        host: ty::HostPolarity::Maybe,
+                    }) => trait_ref,
+                    _ => bug!("converted {clause:?}"),
+                }),
+                span,
+            )
+        })),
+    }
+}
+
+pub(super) fn implied_const_bounds<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
+    if !tcx.is_conditionally_const(def_id) {
+        bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
+    }
+
+    let bounds = match tcx.hir_node_by_def_id(def_id) {
+        Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
+            implied_predicates_with_filter(
+                tcx,
+                def_id.to_def_id(),
+                PredicateFilter::SelfConstIfConst,
+            )
+        }
+        Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => {
+            explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
+        }
+        _ => bug!("implied_const_bounds called on wrong item: {def_id:?}"),
+    };
+
+    bounds.map_bound(|bounds| {
+        &*tcx.arena.alloc_from_iter(bounds.iter().copied().map(|(clause, span)| {
+            (
+                clause.kind().map_bound(|clause| match clause {
+                    ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
+                        trait_ref,
+                        host: ty::HostPolarity::Maybe,
+                    }) => trait_ref,
+                    _ => bug!("converted {clause:?}"),
+                }),
+                span,
+            )
+        }))
+    })
+}
diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs
index 1ccb7faaf30..4d3595965c9 100644
--- a/compiler/rustc_hir_analysis/src/delegation.rs
+++ b/compiler/rustc_hir_analysis/src/delegation.rs
@@ -186,7 +186,6 @@ impl<'tcx> GenericsBuilder<'tcx> {
             param_def_id_to_index,
             has_self,
             has_late_bound_regions: sig_generics.has_late_bound_regions,
-            host_effect_index: sig_generics.host_effect_index,
         }
     }
 }
@@ -472,10 +471,6 @@ fn check_constraints<'tcx>(
         }));
     };
 
-    if tcx.has_host_param(sig_id) {
-        emit("delegation to a function with effect parameter is not supported yet");
-    }
-
     if let Some(local_sig_id) = sig_id.as_local()
         && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some()
     {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 2b0e1350108..c902e85c267 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -154,7 +154,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         for hir_bound in hir_bounds {
             // In order to avoid cycles, when we're lowering `SelfThatDefines`,
             // we skip over any traits that don't define the given associated type.
-
             if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter {
                 if let Some(trait_ref) = hir_bound.trait_ref()
                     && let Some(trait_did) = trait_ref.trait_def_id()
@@ -193,6 +192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     );
                 }
                 hir::GenericBound::Outlives(lifetime) => {
+                    // `ConstIfConst` is only interested in `~const` bounds.
+                    if matches!(
+                        predicate_filter,
+                        PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst
+                    ) {
+                        continue;
+                    }
+
                     let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
                     bounds.push_region_bound(
                         self.tcx(),
@@ -392,21 +399,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     },
                 );
 
-                bounds.push_projection_bound(
-                    tcx,
-                    projection_term.map_bound(|projection_term| ty::ProjectionPredicate {
-                        projection_term,
-                        term,
-                    }),
-                    constraint.span,
-                );
+                match predicate_filter {
+                    PredicateFilter::All
+                    | PredicateFilter::SelfOnly
+                    | PredicateFilter::SelfThatDefines(_)
+                    | PredicateFilter::SelfAndAssociatedTypeBounds => {
+                        bounds.push_projection_bound(
+                            tcx,
+                            projection_term.map_bound(|projection_term| ty::ProjectionPredicate {
+                                projection_term,
+                                term,
+                            }),
+                            constraint.span,
+                        );
+                    }
+                    // `ConstIfConst` is only interested in `~const` bounds.
+                    PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
+                }
             }
             // Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
             // to a bound involving a projection: `<T as Iterator>::Item: Debug`.
             hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
                 match predicate_filter {
-                    PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {}
-                    PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
+                    PredicateFilter::All
+                    | PredicateFilter::SelfAndAssociatedTypeBounds
+                    | PredicateFilter::ConstIfConst => {
                         let projection_ty = projection_term
                             .map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
                         // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
@@ -421,6 +438,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             predicate_filter,
                         );
                     }
+                    PredicateFilter::SelfOnly
+                    | PredicateFilter::SelfThatDefines(_)
+                    | PredicateFilter::SelfConstIfConst => {}
                 }
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 2cee7c77aa5..3449270564a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -78,7 +78,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 ty::ClauseKind::RegionOutlives(_)
                 | ty::ClauseKind::ConstArgHasType(..)
                 | ty::ClauseKind::WellFormed(_)
-                | ty::ClauseKind::ConstEvaluatable(_) => {
+                | ty::ClauseKind::ConstEvaluatable(_)
+                | ty::ClauseKind::HostEffect(..) => {
                     span_bug!(span, "did not expect {pred} clause in object bounds");
                 }
             }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index a73a2f925cd..863c077a9e0 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -81,6 +81,12 @@ pub enum PredicateFilter {
     /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
     /// and `<Self as Tr>::A: B`.
     SelfAndAssociatedTypeBounds,
+
+    /// Filter only the `~const` bounds, which are lowered into `HostEffect` clauses.
+    ConstIfConst,
+
+    /// Filter only the `~const` bounds which are *also* in the supertrait position.
+    SelfConstIfConst,
 }
 
 #[derive(Debug)]
@@ -693,16 +699,49 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             bound_vars,
         );
 
-        debug!(?poly_trait_ref);
-        bounds.push_trait_bound(
-            tcx,
-            self.item_def_id().to_def_id(),
-            poly_trait_ref,
-            span,
-            polarity,
-            constness,
-            predicate_filter,
-        );
+        match predicate_filter {
+            PredicateFilter::All
+            | PredicateFilter::SelfOnly
+            | PredicateFilter::SelfThatDefines(..)
+            | PredicateFilter::SelfAndAssociatedTypeBounds => {
+                debug!(?poly_trait_ref);
+                bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
+
+                match constness {
+                    Some(ty::BoundConstness::Const) => {
+                        if polarity == ty::PredicatePolarity::Positive {
+                            bounds.push_const_bound(
+                                tcx,
+                                poly_trait_ref,
+                                ty::HostPolarity::Const,
+                                span,
+                            );
+                        }
+                    }
+                    Some(ty::BoundConstness::ConstIfConst) => {
+                        // We don't emit a const bound here, since that would mean that we
+                        // unconditionally need to prove a `HostEffect` predicate, even when
+                        // the predicates are being instantiated in a non-const context. This
+                        // is instead handled in the `const_conditions` query.
+                    }
+                    None => {}
+                }
+            }
+            // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert
+            // `~const` bounds. All other predicates are handled in their respective queries.
+            //
+            // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering
+            // here because we only call this on self bounds, and deal with the recursive case
+            // in `lower_assoc_item_constraint`.
+            PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness {
+                Some(ty::BoundConstness::ConstIfConst) => {
+                    if polarity == ty::PredicatePolarity::Positive {
+                        bounds.push_const_bound(tcx, poly_trait_ref, ty::HostPolarity::Maybe, span);
+                    }
+                }
+                None | Some(ty::BoundConstness::Const) => {}
+            },
+        }
 
         let mut dup_constraints = FxIndexMap::default();
         for constraint in trait_segment.args().constraints {
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 0355adfcb11..a394fc2fbb1 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -530,6 +530,7 @@ fn trait_specialization_kind<'tcx>(
         | ty::ClauseKind::Projection(_)
         | ty::ClauseKind::ConstArgHasType(..)
         | ty::ClauseKind::WellFormed(_)
-        | ty::ClauseKind::ConstEvaluatable(..) => None,
+        | ty::ClauseKind::ConstEvaluatable(..)
+        | ty::ClauseKind::HostEffect(..) => None,
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
index f576499ecac..2c1d443f951 100644
--- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
@@ -53,7 +53,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
                     | ty::ClauseKind::Projection(_)
                     | ty::ClauseKind::ConstArgHasType(_, _)
                     | ty::ClauseKind::WellFormed(_)
-                    | ty::ClauseKind::ConstEvaluatable(_) => {}
+                    | ty::ClauseKind::ConstEvaluatable(_)
+                    | ty::ClauseKind::HostEffect(..) => {}
                 }
             }
 
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 3ba9c76bcee..61214b99215 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2134,7 +2134,7 @@ impl<'a> State<'a> {
                     self.print_type(default);
                 }
             }
-            GenericParamKind::Const { ty, ref default, is_host_effect: _, synthetic: _ } => {
+            GenericParamKind::Const { ty, ref default, synthetic: _ } => {
                 self.word_space(":");
                 self.print_type(ty);
                 if let Some(default) = default {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 06e2a5e3493..190e405282c 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -20,7 +20,7 @@ use rustc_target::spec::abi;
 use rustc_trait_selection::error_reporting::traits::DefIdOrName;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use tracing::{debug, instrument, trace};
+use tracing::{debug, instrument};
 
 use super::method::MethodCallee;
 use super::method::probe::ProbeScope;
@@ -843,29 +843,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         callee_did: DefId,
         callee_args: GenericArgsRef<'tcx>,
     ) {
-        let tcx = self.tcx;
-
-        // 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 };
-
-        let effect = tcx.expected_host_effect_param_for_body(self.body_id);
-
-        trace!(?effect, ?generics, ?callee_args);
+        // FIXME(effects): We should be enforcing these effects unconditionally.
+        // This can be done as soon as we convert the standard library back to
+        // using const traits, since if we were to enforce these conditions now,
+        // we'd fail on basically every builtin trait call (i.e. `1 + 2`).
+        if !self.tcx.features().effects() {
+            return;
+        }
 
-        let param = callee_args.const_at(host_effect_index);
-        let cause = self.misc(span);
-        // We know the type of `effect` to be `bool`, there will be no opaque type inference.
-        match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::Yes, effect, param) {
-            Ok(infer::InferOk { obligations, value: () }) => {
-                self.register_predicates(obligations);
+        let host = match self.tcx.hir().body_const_context(self.body_id) {
+            Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {
+                ty::HostPolarity::Const
             }
-            Err(e) => {
-                // FIXME(effects): better diagnostic
-                self.err_ctxt()
-                    .report_mismatched_consts(&cause, self.param_env, effect, param, e)
-                    .emit();
+            Some(hir::ConstContext::ConstFn) => ty::HostPolarity::Maybe,
+            None => return,
+        };
+
+        // FIXME(effects): Should this be `is_const_fn_raw`? It depends on if we move
+        // const stability checking here too, I guess.
+        if self.tcx.is_conditionally_const(callee_did) {
+            let q = self.tcx.const_conditions(callee_did);
+            // FIXME(effects): Use this span with a better cause code.
+            for (cond, _) in q.instantiate(self.tcx, callee_args) {
+                self.register_predicate(Obligation::new(
+                    self.tcx,
+                    self.misc(span),
+                    self.param_env,
+                    cond.to_host_effect_clause(self.tcx, host),
+                ));
             }
+        } else {
+            // FIXME(effects): This should eventually be caught here.
+            // For now, though, we defer some const checking to MIR.
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 4fd508ab896..68776c52555 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -7,8 +7,6 @@ use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet};
 use rustc_hir as hir;
 use rustc_hir::HirId;
 use rustc_hir::intravisit::Visitor;
-use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
-use rustc_middle::bug;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
 use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
@@ -48,7 +46,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
             self.fulfillment_cx.borrow_mut().pending_obligations()
         );
 
-        let fallback_occurred = self.fallback_types() | self.fallback_effects();
+        let fallback_occurred = self.fallback_types();
 
         if !fallback_occurred {
             return;
@@ -103,31 +101,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         fallback_occurred
     }
 
-    fn fallback_effects(&self) -> bool {
-        let unsolved_effects = self.unsolved_effects();
-
-        if unsolved_effects.is_empty() {
-            return false;
-        }
-
-        // not setting the `fallback_has_occurred` field here because
-        // that field is only used for type fallback diagnostics.
-        for effect in unsolved_effects {
-            let expected = self.tcx.consts.true_;
-            let cause = self.misc(DUMMY_SP);
-            match self.at(&cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, effect) {
-                Ok(InferOk { obligations, value: () }) => {
-                    self.register_predicates(obligations);
-                }
-                Err(e) => {
-                    bug!("cannot eq unsolved effect: {e:?}")
-                }
-            }
-        }
-
-        true
-    }
-
     // Tries to apply a fallback to `ty` if it is an unsolved variable.
     //
     // - Unconstrained ints are replaced with `i32`.
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index d2d311ef565..0fc566c58f7 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1262,15 +1262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
                         self.fcx.ty_infer(Some(param), inf.span).into()
                     }
-                    (
-                        &GenericParamDefKind::Const { has_default, is_host_effect, .. },
-                        GenericArg::Infer(inf),
-                    ) => {
-                        if has_default && is_host_effect {
-                            self.fcx.var_for_effect(param)
-                        } else {
-                            self.fcx.ct_infer(Some(param), inf.span).into()
-                        }
+                    (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
+                        self.fcx.ct_infer(Some(param), inf.span).into()
                     }
                     _ => unreachable!(),
                 }
@@ -1305,20 +1298,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.fcx.var_for_def(self.span, param)
                         }
                     }
-                    GenericParamDefKind::Const { has_default, is_host_effect, .. } => {
+                    GenericParamDefKind::Const { has_default, .. } => {
                         if has_default {
-                            // N.B. this is a bit of a hack. `infer_args` is passed depending on
-                            // whether the user has provided generic args. E.g. for `Vec::new`
-                            // we would have to infer the generic types. However, for `Vec::<T>::new`
-                            // where the allocator param `A` has a default we will *not* infer. But
-                            // for effect params this is a different story: if the user has not written
-                            // anything explicit for the effect param, we always need to try to infer
-                            // it before falling back to default, such that a `const fn` such as
-                            // `needs_drop::<()>` can still be called in const contexts. (if we defaulted
-                            // instead of inferred, typeck would error)
-                            if is_host_effect {
-                                return self.fcx.var_for_effect(param);
-                            } else if !infer_args {
+                            if !infer_args {
                                 return tcx
                                     .const_param_default(param.def_id)
                                     .instantiate(tcx, preceding_args)
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
index 693cb4465cc..eb5fe3a86e4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
@@ -52,6 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             | ty::PredicateKind::AliasRelate(..)
             | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
             | ty::PredicateKind::ConstEquate(..)
+            | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
             | ty::PredicateKind::Ambiguous => false,
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 4123feebb40..3940d138deb 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -247,12 +247,6 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
     fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
         // FIXME ideally this shouldn't use unwrap
         match param {
-            Some(
-                param @ ty::GenericParamDef {
-                    kind: ty::GenericParamDefKind::Const { is_host_effect: true, .. },
-                    ..
-                },
-            ) => self.var_for_effect(param).as_const().unwrap(),
             Some(param) => self.var_for_def(span, param).as_const().unwrap(),
             None => self.next_const_var(span),
         }
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 69b9be00276..e20a0cb67c3 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -369,17 +369,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
         let (obligation, args) =
             self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types);
-        // FIXME(effects) find a better way to do this
-        // Operators don't have generic methods, but making them `#[const_trait]` gives them
-        // `const host: bool`.
-        let args = if self.tcx.is_const_trait(trait_def_id) {
-            self.tcx.mk_args_from_iter(
-                args.iter()
-                    .chain([self.tcx.expected_host_effect_param_for_body(self.body_id).into()]),
-            )
-        } else {
-            args
-        };
         self.construct_obligation_for_trait(m_name, trait_def_id, obligation, args)
     }
 
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index b60fa8bbfa1..569fdea11ce 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -813,7 +813,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 | ty::ClauseKind::Projection(_)
                 | ty::ClauseKind::ConstArgHasType(_, _)
                 | ty::ClauseKind::WellFormed(_)
-                | ty::ClauseKind::ConstEvaluatable(_) => None,
+                | ty::ClauseKind::ConstEvaluatable(_)
+                | ty::ClauseKind::HostEffect(..) => None,
             }
         });
 
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index e3519dfb028..90d07964fda 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -489,17 +489,6 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                     }
                 }
             }
-            ty::ConstKind::Infer(InferConst::EffectVar(vid)) => {
-                match self.infcx.unwrap().probe_effect_var(vid) {
-                    Some(value) => return self.fold_const(value),
-                    None => {
-                        return self.canonicalize_const_var(
-                            CanonicalVarInfo { kind: CanonicalVarKind::Effect },
-                            ct,
-                        );
-                    }
-                }
-            }
             ty::ConstKind::Infer(InferConst::Fresh(_)) => {
                 bug!("encountered a fresh const during canonicalization")
             }
@@ -700,8 +689,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             .iter()
             .map(|v| CanonicalVarInfo {
                 kind: match v.kind {
-                    CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
-                    | CanonicalVarKind::Effect => {
+                    CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
                         return *v;
                     }
                     CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 8caedcd4053..fb5fc3a53fe 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -24,7 +24,6 @@
 pub use instantiate::CanonicalExt;
 use rustc_index::IndexVec;
 pub use rustc_middle::infer::canonical::*;
-use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, GenericArg, List, Ty, TyCtxt};
 use rustc_span::Span;
@@ -145,15 +144,6 @@ impl<'tcx> InferCtxt<'tcx> {
             CanonicalVarKind::Const(ui) => {
                 self.next_const_var_in_universe(span, universe_map(ui)).into()
             }
-            CanonicalVarKind::Effect => {
-                let vid = self
-                    .inner
-                    .borrow_mut()
-                    .effect_unification_table()
-                    .new_key(EffectVarValue::Unknown)
-                    .vid;
-                ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid)).into()
-            }
             CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => {
                 let universe_mapped = universe_map(universe);
                 let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound };
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
index 57007752cad..0c151a11ad4 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -1,6 +1,5 @@
 ///! Definition of `InferCtxtLike` from the librarified type layer.
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::solve::SolverMode;
 use rustc_middle::ty::fold::TypeFoldable;
@@ -88,15 +87,6 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         }
     }
 
-    fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> {
-        match self.probe_effect_var(vid) {
-            Some(ct) => ct,
-            None => {
-                ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(self.root_effect_var(vid)))
-            }
-        }
-    }
-
     fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
         self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
     }
@@ -152,10 +142,6 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         self.inner.borrow_mut().const_unification_table().union(a, b);
     }
 
-    fn equate_effect_vids_raw(&self, a: rustc_type_ir::EffectVid, b: rustc_type_ir::EffectVid) {
-        self.inner.borrow_mut().effect_unification_table().union(a, b);
-    }
-
     fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
         &self,
         relation: &mut R,
@@ -189,13 +175,6 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         self.inner.borrow_mut().float_unification_table().union_value(vid, value);
     }
 
-    fn instantiate_effect_var_raw(&self, vid: rustc_type_ir::EffectVid, value: ty::Const<'tcx>) {
-        self.inner
-            .borrow_mut()
-            .effect_unification_table()
-            .union_value(vid, EffectVarValue::Known(value));
-    }
-
     fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
         &self,
         relation: &mut R,
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index c4294111ebe..28eac5b7496 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -153,15 +153,6 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
                 drop(inner);
                 self.freshen_const(input, ty::InferConst::Fresh)
             }
-            ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => {
-                let mut inner = self.infcx.inner.borrow_mut();
-                let input =
-                    inner.effect_unification_table().probe_value(v).known().ok_or_else(|| {
-                        ty::InferConst::EffectVar(inner.effect_unification_table().find(v).vid)
-                    });
-                drop(inner);
-                self.freshen_const(input, ty::InferConst::Fresh)
-            }
             ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
                 if i >= self.const_freshen_count {
                     bug!(
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 5afdf3c2454..be43cba97f0 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -26,9 +26,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::extension;
 pub use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues};
-use rustc_middle::infer::unify_key::{
-    ConstVariableOrigin, ConstVariableValue, ConstVidKey, EffectVarValue, EffectVidKey,
-};
+use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
 use rustc_middle::traits::select;
@@ -39,7 +37,7 @@ use rustc_middle::ty::fold::{
 };
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{
-    self, ConstVid, EffectVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef,
+    self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef,
     GenericParamDefKind, InferConst, IntVid, Ty, TyCtxt, TyVid,
 };
 use rustc_middle::{bug, span_bug};
@@ -117,9 +115,6 @@ pub struct InferCtxtInner<'tcx> {
     /// Map from floating variable to the kind of float it represents.
     float_unification_storage: ut::UnificationTableStorage<ty::FloatVid>,
 
-    /// Map from effect variable to the effect param it represents.
-    effect_unification_storage: ut::UnificationTableStorage<EffectVidKey<'tcx>>,
-
     /// Tracks the set of region variables and the constraints between them.
     ///
     /// This is initially `Some(_)` but when
@@ -176,7 +171,6 @@ impl<'tcx> InferCtxtInner<'tcx> {
             const_unification_storage: Default::default(),
             int_unification_storage: Default::default(),
             float_unification_storage: Default::default(),
-            effect_unification_storage: Default::default(),
             region_constraint_storage: Some(Default::default()),
             region_obligations: vec![],
             opaque_type_storage: Default::default(),
@@ -228,10 +222,6 @@ impl<'tcx> InferCtxtInner<'tcx> {
         self.const_unification_storage.with_log(&mut self.undo_log)
     }
 
-    fn effect_unification_table(&mut self) -> UnificationTable<'_, 'tcx, EffectVidKey<'tcx>> {
-        self.effect_unification_storage.with_log(&mut self.undo_log)
-    }
-
     #[inline]
     pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx> {
         self.region_constraint_storage
@@ -524,7 +514,6 @@ impl fmt::Display for FixupError {
             ),
             Ty(_) => write!(f, "unconstrained type"),
             Const(_) => write!(f, "unconstrained const value"),
-            Effect(_) => write!(f, "unconstrained effect value"),
         }
     }
 }
@@ -726,17 +715,6 @@ impl<'tcx> InferCtxt<'tcx> {
         vars
     }
 
-    pub fn unsolved_effects(&self) -> Vec<ty::Const<'tcx>> {
-        let mut inner = self.inner.borrow_mut();
-        let mut table = inner.effect_unification_table();
-
-        (0..table.len())
-            .map(|i| ty::EffectVid::from_usize(i))
-            .filter(|&vid| table.probe_value(vid).is_unknown())
-            .map(|v| ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v)))
-            .collect()
-    }
-
     #[instrument(skip(self), level = "debug")]
     pub fn sub_regions(
         &self,
@@ -899,13 +877,6 @@ impl<'tcx> InferCtxt<'tcx> {
         ty::Const::new_var(self.tcx, vid)
     }
 
-    fn next_effect_var(&self) -> ty::Const<'tcx> {
-        let effect_vid =
-            self.inner.borrow_mut().effect_unification_table().new_key(EffectVarValue::Unknown).vid;
-
-        ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid))
-    }
-
     pub fn next_int_var(&self) -> Ty<'tcx> {
         let next_int_var_id =
             self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown);
@@ -991,10 +962,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
                 Ty::new_var(self.tcx, ty_var_id).into()
             }
-            GenericParamDefKind::Const { is_host_effect, .. } => {
-                if is_host_effect {
-                    return self.var_for_effect(param);
-                }
+            GenericParamDefKind::Const { .. } => {
                 let origin = ConstVariableOrigin { param_def_id: Some(param.def_id), span };
                 let const_var_id = self
                     .inner
@@ -1007,16 +975,6 @@ impl<'tcx> InferCtxt<'tcx> {
         }
     }
 
-    pub fn var_for_effect(&self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
-        let ty = self
-            .tcx
-            .type_of(param.def_id)
-            .no_bound_vars()
-            .expect("const parameter types cannot be generic");
-        debug_assert_eq!(self.tcx.types.bool, ty);
-        self.next_effect_var().into()
-    }
-
     /// Given a set of generics defined on a type or impl, returns the generic parameters mapping
     /// each type/region parameter to a fresh inference variable.
     pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> {
@@ -1142,13 +1100,6 @@ impl<'tcx> InferCtxt<'tcx> {
                     .probe_value(vid)
                     .known()
                     .unwrap_or(ct),
-                InferConst::EffectVar(vid) => self
-                    .inner
-                    .borrow_mut()
-                    .effect_unification_table()
-                    .probe_value(vid)
-                    .known()
-                    .unwrap_or(ct),
                 InferConst::Fresh(_) => ct,
             },
             ty::ConstKind::Param(_)
@@ -1169,10 +1120,6 @@ impl<'tcx> InferCtxt<'tcx> {
         self.inner.borrow_mut().const_unification_table().find(var).vid
     }
 
-    pub fn root_effect_var(&self, var: ty::EffectVid) -> ty::EffectVid {
-        self.inner.borrow_mut().effect_unification_table().find(var).vid
-    }
-
     /// Resolves an int var to a rigid int type, if it was constrained to one,
     /// or else the root int var in the unification table.
     pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
@@ -1238,10 +1185,6 @@ impl<'tcx> InferCtxt<'tcx> {
         }
     }
 
-    pub fn probe_effect_var(&self, vid: EffectVid) -> Option<ty::Const<'tcx>> {
-        self.inner.borrow_mut().effect_unification_table().probe_value(vid).known()
-    }
-
     /// Attempts to resolve all type/region/const variables in
     /// `value`. Region inference must have been run already (e.g.,
     /// by calling `resolve_regions_and_report_errors`). If some
@@ -1511,14 +1454,6 @@ impl<'tcx> InferCtxt<'tcx> {
                     ConstVariableValue::Known { .. } => true,
                 }
             }
-
-            TyOrConstInferVar::Effect(v) => {
-                // If `probe_value` returns `Some`, it never equals
-                // `ty::ConstKind::Infer(ty::InferConst::Effect(v))`.
-                //
-                // Not `inlined_probe_value(v)` because this call site is colder.
-                self.probe_effect_var(v).is_some()
-            }
         }
     }
 
@@ -1545,8 +1480,6 @@ pub enum TyOrConstInferVar {
 
     /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
     Const(ConstVid),
-    /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::EffectVar(_))`.
-    Effect(EffectVid),
 }
 
 impl<'tcx> TyOrConstInferVar {
@@ -1577,7 +1510,6 @@ impl<'tcx> TyOrConstInferVar {
     fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
         match ct.kind() {
             ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
-            ty::ConstKind::Infer(InferConst::EffectVar(v)) => Some(TyOrConstInferVar::Effect(v)),
             _ => None,
         }
     }
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index e23bb1aaa56..1afe50e336d 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -24,19 +24,9 @@ pub fn explicit_outlives_bounds<'tcx>(
     param_env
         .caller_bounds()
         .into_iter()
-        .map(ty::Clause::kind)
+        .filter_map(ty::Clause::as_region_outlives_clause)
         .filter_map(ty::Binder::no_bound_vars)
-        .filter_map(move |kind| match kind {
-            ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
-                Some(OutlivesBound::RegionSubRegion(r_b, r_a))
-            }
-            ty::ClauseKind::Trait(_)
-            | ty::ClauseKind::TypeOutlives(_)
-            | ty::ClauseKind::Projection(_)
-            | ty::ClauseKind::ConstArgHasType(_, _)
-            | ty::ClauseKind::WellFormed(_)
-            | ty::ClauseKind::ConstEvaluatable(_) => None,
-        })
+        .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a))
 }
 
 impl<'tcx> InferCtxt<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 7049444db9b..32817dbcb21 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -660,7 +660,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
                     }
                 }
             }
-            ty::ConstKind::Infer(InferConst::EffectVar(_)) => Ok(c),
             // FIXME: Unevaluated constants are also not rigid, so the current
             // approach of always relating them structurally is incomplete.
             //
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 64cc76f827e..6ec2e0152f0 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -176,9 +176,6 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
                 ty::ConstKind::Infer(InferConst::Fresh(_)) => {
                     bug!("Unexpected const in full const resolver: {:?}", c);
                 }
-                ty::ConstKind::Infer(InferConst::EffectVar(evid)) => {
-                    return Err(FixupError { unresolved: super::TyOrConstInferVar::Effect(evid) });
-                }
                 _ => {}
             }
             c.try_super_fold_with(self)
diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
index 613cebc266d..394e07a81e7 100644
--- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -4,7 +4,6 @@ use rustc_data_structures::{snapshot_vec as sv, unify as ut};
 use rustc_middle::infer::unify_key::{ConstVariableValue, ConstVidKey};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
-use rustc_type_ir::EffectVid;
 use rustc_type_ir::visit::TypeVisitableExt;
 use tracing::instrument;
 use ut::UnifyKey;
@@ -129,7 +128,6 @@ struct SnapshotVarData {
     int_vars: Range<IntVid>,
     float_vars: Range<FloatVid>,
     const_vars: (Range<ConstVid>, Vec<ConstVariableOrigin>),
-    effect_vars: Range<EffectVid>,
 }
 
 impl SnapshotVarData {
@@ -148,30 +146,16 @@ impl SnapshotVarData {
             &mut inner.const_unification_table(),
             vars_pre_snapshot.const_var_len,
         );
-        let effect_vars = vars_since_snapshot(
-            &inner.effect_unification_table(),
-            vars_pre_snapshot.effect_var_len,
-        );
-        let effect_vars = effect_vars.start.vid..effect_vars.end.vid;
-
-        SnapshotVarData { region_vars, type_vars, int_vars, float_vars, const_vars, effect_vars }
+        SnapshotVarData { region_vars, type_vars, int_vars, float_vars, const_vars }
     }
 
     fn is_empty(&self) -> bool {
-        let SnapshotVarData {
-            region_vars,
-            type_vars,
-            int_vars,
-            float_vars,
-            const_vars,
-            effect_vars,
-        } = self;
+        let SnapshotVarData { region_vars, type_vars, int_vars, float_vars, const_vars } = self;
         region_vars.0.is_empty()
             && type_vars.0.is_empty()
             && int_vars.is_empty()
             && float_vars.is_empty()
             && const_vars.0.is_empty()
-            && effect_vars.is_empty()
     }
 }
 
@@ -258,13 +242,6 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> {
                         ct
                     }
                 }
-                ty::InferConst::EffectVar(vid) => {
-                    if self.snapshot_vars.effect_vars.contains(&vid) {
-                        self.infcx.next_effect_var()
-                    } else {
-                        ct
-                    }
-                }
                 ty::InferConst::Fresh(_) => {
                     unreachable!("unexpected fresh infcx var")
                 }
diff --git a/compiler/rustc_infer/src/infer/snapshot/mod.rs b/compiler/rustc_infer/src/infer/snapshot/mod.rs
index fa813500c54..b16c80cf201 100644
--- a/compiler/rustc_infer/src/infer/snapshot/mod.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/mod.rs
@@ -23,7 +23,6 @@ struct VariableLengths {
     int_var_len: usize,
     float_var_len: usize,
     const_var_len: usize,
-    effect_var_len: usize,
 }
 
 impl<'tcx> InferCtxt<'tcx> {
@@ -35,7 +34,6 @@ impl<'tcx> InferCtxt<'tcx> {
             int_var_len: inner.int_unification_table().len(),
             float_var_len: inner.float_unification_table().len(),
             const_var_len: inner.const_unification_table().len(),
-            effect_var_len: inner.effect_unification_table().len(),
         }
     }
 
diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
index 79ea0915c9c..713389f4618 100644
--- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
@@ -2,7 +2,7 @@ use std::marker::PhantomData;
 
 use rustc_data_structures::undo_log::{Rollback, UndoLogs};
 use rustc_data_structures::{snapshot_vec as sv, unify as ut};
-use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey, RegionVidKey};
+use rustc_middle::infer::unify_key::{ConstVidKey, RegionVidKey};
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey};
 use tracing::debug;
 
@@ -22,7 +22,6 @@ pub(crate) enum UndoLog<'tcx> {
     ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
     IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
     FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
-    EffectUnificationTable(sv::UndoLog<ut::Delegate<EffectVidKey<'tcx>>>),
     RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
     RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
     ProjectionCache(traits::UndoLog<'tcx>),
@@ -50,7 +49,6 @@ impl_from! {
     FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
 
     ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
-    EffectUnificationTable(sv::UndoLog<ut::Delegate<EffectVidKey<'tcx>>>),
 
     RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
     ProjectionCache(traits::UndoLog<'tcx>),
@@ -65,7 +63,6 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
             UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo),
             UndoLog::IntUnificationTable(undo) => self.int_unification_storage.reverse(undo),
             UndoLog::FloatUnificationTable(undo) => self.float_unification_storage.reverse(undo),
-            UndoLog::EffectUnificationTable(undo) => self.effect_unification_storage.reverse(undo),
             UndoLog::RegionConstraintCollector(undo) => {
                 self.region_constraint_storage.as_mut().unwrap().reverse(undo)
             }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 5c5cd99345e..a1e4bc75c21 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1554,7 +1554,9 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
                     // Ignore bounds that a user can't type
                     | ClauseKind::WellFormed(..)
                     // FIXME(generic_const_exprs): `ConstEvaluatable` can be written
-                    | ClauseKind::ConstEvaluatable(..)  => continue,
+                    | ClauseKind::ConstEvaluatable(..)
+                    // Users don't write this directly, only via another trait ref.
+                    | ty::ClauseKind::HostEffect(..) => continue,
                 };
                 if predicate.is_global() {
                     cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds {
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 83a8ca4307e..1c27e1daa90 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -542,11 +542,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
     }
 
     fn check_generic_param(&mut self, cx: &LateContext<'_>, param: &hir::GenericParam<'_>) {
-        if let GenericParamKind::Const { is_host_effect, .. } = param.kind {
-            // `host` params are explicitly allowed to be lowercase.
-            if is_host_effect {
-                return;
-            }
+        if let GenericParamKind::Const { .. } = param.kind {
             NonUpperCaseGlobals::check_upper_case(cx, "const parameter", &param.name.ident());
         }
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7bb40996d58..71c7231a788 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -275,6 +275,8 @@ provide! { tcx, def_id, other, cdata,
     impl_parent => { table }
     defaultness => { table_direct }
     constness => { table_direct }
+    const_conditions => { table }
+    implied_const_bounds => { table_defaulted_array }
     coerce_unsized_info => {
         Ok(cdata
             .root
@@ -330,7 +332,6 @@ provide! { tcx, def_id, other, cdata,
             .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
     }
 
-    associated_type_for_effects => { table }
     associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array }
 
     visibility => { cdata.get_visibility(def_id.index) }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index ec678c7515b..e06c86ae4c0 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1433,6 +1433,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     }
                 }
             }
+            if tcx.is_conditionally_const(def_id) {
+                record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id));
+            }
             if should_encode_type(tcx, local_id, def_kind) {
                 record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
             }
@@ -1456,10 +1459,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     self.tcx.explicit_super_predicates_of(def_id).skip_binder());
                 record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
                     self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
-
                 let module_children = self.tcx.module_children_local(local_id);
                 record_array!(self.tables.module_children_non_reexports[def_id] <-
                     module_children.iter().map(|child| child.res.def_id().index));
+                if self.tcx.is_const_trait(def_id) {
+                    record_defaulted_array!(self.tables.implied_const_bounds[def_id]
+                        <- self.tcx.implied_const_bounds(def_id).skip_binder());
+                }
             }
             if let DefKind::TraitAlias = def_kind {
                 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
@@ -1479,9 +1485,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 for &def_id in associated_item_def_ids {
                     self.encode_info_for_assoc_item(def_id);
                 }
-                if let Some(assoc_def_id) = self.tcx.associated_type_for_effects(def_id) {
-                    record!(self.tables.associated_type_for_effects[def_id] <- assoc_def_id);
-                }
             }
             if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind
                 && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id)
@@ -1652,6 +1655,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 if let ty::AssocKind::Type = item.kind {
                     self.encode_explicit_item_bounds(def_id);
                     self.encode_explicit_item_super_predicates(def_id);
+                    if tcx.is_conditionally_const(def_id) {
+                        record_defaulted_array!(self.tables.implied_const_bounds[def_id]
+                            <- self.tcx.implied_const_bounds(def_id).skip_binder());
+                    }
                 }
             }
             AssocItemContainer::ImplContainer => {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 79bd1c13b12..a00ca27aacc 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -392,9 +392,9 @@ define_tables! {
     inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
+    implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
     associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
-    associated_type_for_effects: Table<DefIndex, Option<LazyValue<DefId>>>,
     opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
     is_effects_desugaring: Table<DefIndex, bool>,
     unused_generic_params: Table<DefIndex, UnusedGenericParams>,
@@ -436,6 +436,7 @@ define_tables! {
     thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,
     impl_parent: Table<DefIndex, RawDefId>,
     constness: Table<DefIndex, hir::Constness>,
+    const_conditions: Table<DefIndex, LazyValue<ty::ConstConditions<'static>>>,
     defaultness: Table<DefIndex, hir::Defaultness>,
     // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
     coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index cf692b145b8..7f9211043d6 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -172,70 +172,3 @@ impl<'tcx> UnifyValue for ConstVariableValue<'tcx> {
         }
     }
 }
-
-/// values for the effect inference variable
-#[derive(Clone, Copy, Debug)]
-pub enum EffectVarValue<'tcx> {
-    Unknown,
-    Known(ty::Const<'tcx>),
-}
-
-impl<'tcx> EffectVarValue<'tcx> {
-    pub fn known(self) -> Option<ty::Const<'tcx>> {
-        match self {
-            EffectVarValue::Unknown => None,
-            EffectVarValue::Known(value) => Some(value),
-        }
-    }
-
-    pub fn is_unknown(self) -> bool {
-        match self {
-            EffectVarValue::Unknown => true,
-            EffectVarValue::Known(_) => false,
-        }
-    }
-}
-
-impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
-    type Error = NoError;
-
-    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
-        match (*value1, *value2) {
-            (EffectVarValue::Unknown, EffectVarValue::Unknown) => Ok(EffectVarValue::Unknown),
-            (EffectVarValue::Unknown, EffectVarValue::Known(val))
-            | (EffectVarValue::Known(val), EffectVarValue::Unknown) => {
-                Ok(EffectVarValue::Known(val))
-            }
-            (EffectVarValue::Known(_), EffectVarValue::Known(_)) => {
-                bug!("equating known inference variables: {value1:?} {value2:?}")
-            }
-        }
-    }
-}
-
-#[derive(PartialEq, Copy, Clone, Debug)]
-pub struct EffectVidKey<'tcx> {
-    pub vid: ty::EffectVid,
-    pub phantom: PhantomData<ty::Const<'tcx>>,
-}
-
-impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
-    fn from(vid: ty::EffectVid) -> Self {
-        EffectVidKey { vid, phantom: PhantomData }
-    }
-}
-
-impl<'tcx> UnifyKey for EffectVidKey<'tcx> {
-    type Value = EffectVarValue<'tcx>;
-    #[inline]
-    fn index(&self) -> u32 {
-        self.vid.as_u32()
-    }
-    #[inline]
-    fn from_index(i: u32) -> Self {
-        EffectVidKey::from(ty::EffectVid::from_u32(i))
-    }
-    fn tag() -> &'static str {
-        "EffectVidKey"
-    }
-}
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 48bf4ffced0..5f8427bd707 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -370,6 +370,7 @@ tcx_lifetime! {
     rustc_middle::ty::FnSig,
     rustc_middle::ty::GenericArg,
     rustc_middle::ty::GenericPredicates,
+    rustc_middle::ty::ConstConditions,
     rustc_middle::ty::inhabitedness::InhabitedPredicate,
     rustc_middle::ty::Instance,
     rustc_middle::ty::InstanceKind,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index f8ba606e087..d03fc39c9ad 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -683,6 +683,24 @@ rustc_queries! {
         }
     }
 
+    query const_conditions(
+        key: DefId
+    ) -> ty::ConstConditions<'tcx> {
+        desc { |tcx| "computing the conditions for `{}` to be considered const",
+            tcx.def_path_str(key)
+        }
+        separate_provide_extern
+    }
+
+    query implied_const_bounds(
+        key: DefId
+    ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
+        desc { |tcx| "computing the implied `~const` bounds for `{}`",
+            tcx.def_path_str(key)
+        }
+        separate_provide_extern
+    }
+
     /// To avoid cycles within the predicates of a single item we compute
     /// per-type-parameter predicates for resolving `T::AssocTy`.
     query type_param_predicates(
@@ -854,12 +872,6 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query associated_type_for_effects(def_id: DefId) -> Option<DefId> {
-        desc { |tcx| "creating associated items for effects in `{}`", tcx.def_path_str(def_id) }
-        cache_on_disk_if { def_id.is_local() }
-        separate_provide_extern
-    }
-
     /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding
     /// associated item.
     query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId {
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 7e533bc4291..ef9dfdd2f96 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -387,6 +387,17 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [(ty::Claus
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
+    for [(ty::PolyTraitRef<'tcx>, Span)]
+{
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder
+            .interner()
+            .arena
+            .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
+    }
+}
+
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
     for ty::List<ty::BoundVariableKind>
 {
     fn decode(decoder: &mut D) -> &'tcx Self {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index b682524ae39..eab106a4403 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -78,10 +78,10 @@ use crate::traits::solve::{
 use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
 use crate::ty::{
     self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
-    GenericArgsRef, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst,
-    ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
-    PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
-    Visibility,
+    GenericArgsRef, GenericParamDefKind, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo,
+    ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate,
+    PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
+    TyKind, TyVid, Visibility,
 };
 
 #[allow(rustc::usage_of_ty_tykind)]
@@ -383,6 +383,28 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
     }
 
+    fn is_const_impl(self, def_id: DefId) -> bool {
+        self.is_conditionally_const(def_id)
+    }
+
+    fn const_conditions(
+        self,
+        def_id: DefId,
+    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
+        ty::EarlyBinder::bind(
+            self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
+        )
+    }
+
+    fn implied_const_bounds(
+        self,
+        def_id: DefId,
+    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
+        ty::EarlyBinder::bind(
+            self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
+        )
+    }
+
     fn has_target_features(self, def_id: DefId) -> bool {
         !self.codegen_fn_attrs(def_id).target_features.is_empty()
     }
@@ -646,13 +668,6 @@ bidirectional_lang_item_map! {
     Destruct,
     DiscriminantKind,
     DynMetadata,
-    EffectsCompat,
-    EffectsIntersection,
-    EffectsIntersectionOutput,
-    EffectsMaybe,
-    EffectsNoRuntime,
-    EffectsRuntime,
-    EffectsTyCompat,
     Fn,
     FnMut,
     FnOnce,
@@ -2196,7 +2211,7 @@ macro_rules! nop_slice_lift {
 nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}
 
 TrivialLiftImpls! {
-    ImplPolarity, PredicatePolarity, Promoted
+    ImplPolarity, PredicatePolarity, Promoted, HostPolarity,
 }
 
 macro_rules! sty_debug_print {
@@ -3125,6 +3140,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
+    // FIXME(effects): Please remove this. It's a footgun.
     /// Whether the trait impl is marked const. This does not consider stability or feature gates.
     pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
         let Some(local_def_id) = def_id.as_local() else { return false };
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 8bd2ae9128f..64405d18c7d 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -592,9 +592,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
         match c.kind() {
             ConstKind::Infer(InferConst::Var(_)) if self.infer_suggestable => {}
 
-            // effect variables are always suggestable, because they are not visible
-            ConstKind::Infer(InferConst::EffectVar(_)) => {}
-
             ConstKind::Infer(..)
             | ConstKind::Bound(..)
             | ConstKind::Placeholder(..)
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 92a975c028e..704a197aa49 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -265,6 +265,12 @@ impl FlagComputation {
             ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
                 self.add_args(trait_pred.trait_ref.args);
             }
+            ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
+                trait_ref,
+                host: _,
+            })) => {
+                self.add_args(trait_ref.args);
+            }
             ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
                 a,
                 b,
@@ -354,9 +360,7 @@ impl FlagComputation {
                 self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
                 match infer {
                     InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH),
-                    InferConst::Var(_) | InferConst::EffectVar(_) => {
-                        self.add_flags(TypeFlags::HAS_CT_INFER)
-                    }
+                    InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER),
                 }
             }
             ty::ConstKind::Bound(debruijn, _) => {
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index daf1362e25c..56111ee063e 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -501,12 +501,11 @@ impl<'tcx> GenericArgs<'tcx> {
     #[inline]
     pub fn non_erasable_generics(
         &'tcx self,
-        tcx: TyCtxt<'tcx>,
-        def_id: DefId,
+        // FIXME(effects): Remove these
+        _tcx: TyCtxt<'tcx>,
+        _def_id: DefId,
     ) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> + 'tcx {
-        let generics = tcx.generics_of(def_id);
-        self.iter().enumerate().filter_map(|(i, k)| match k.unpack() {
-            _ if Some(i) == generics.host_effect_index => None,
+        self.iter().filter_map(|k| match k.unpack() {
             ty::GenericArgKind::Lifetime(_) => None,
             generic => Some(generic),
         })
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 63534a3d017..ab1b8fa6a73 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -14,7 +14,7 @@ use crate::ty::{EarlyBinder, GenericArgsRef};
 pub enum GenericParamDefKind {
     Lifetime,
     Type { has_default: bool, synthetic: bool },
-    Const { has_default: bool, is_host_effect: bool, synthetic: bool },
+    Const { has_default: bool, synthetic: bool },
 }
 
 impl GenericParamDefKind {
@@ -81,10 +81,6 @@ impl GenericParamDef {
         }
     }
 
-    pub fn is_host_effect(&self) -> bool {
-        matches!(self.kind, GenericParamDefKind::Const { is_host_effect: true, .. })
-    }
-
     pub fn default_value<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -133,9 +129,6 @@ pub struct Generics {
 
     pub has_self: bool,
     pub has_late_bound_regions: Option<Span>,
-
-    // The index of the host effect when instantiated. (i.e. might be index to parent args)
-    pub host_effect_index: Option<usize>,
 }
 
 impl<'tcx> rustc_type_ir::inherent::GenericsOf<TyCtxt<'tcx>> for &'tcx Generics {
@@ -216,12 +209,10 @@ impl<'tcx> Generics {
     pub fn own_requires_monomorphization(&self) -> bool {
         for param in &self.own_params {
             match param.kind {
-                GenericParamDefKind::Type { .. }
-                | GenericParamDefKind::Const { is_host_effect: false, .. } => {
+                GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
                     return true;
                 }
-                GenericParamDefKind::Lifetime
-                | GenericParamDefKind::Const { is_host_effect: true, .. } => {}
+                GenericParamDefKind::Lifetime => {}
             }
         }
         false
@@ -300,8 +291,6 @@ impl<'tcx> Generics {
             own_params.start = 1;
         }
 
-        let verbose = tcx.sess.verbose_internals();
-
         // Filter the default arguments.
         //
         // This currently uses structural equality instead
@@ -316,8 +305,6 @@ impl<'tcx> Generics {
                 param.default_value(tcx).is_some_and(|default| {
                     default.instantiate(tcx, args) == args[param.index as usize]
                 })
-                // filter out trailing effect params, if we're not in `-Zverbose-internals`.
-                || (!verbose && matches!(param.kind, GenericParamDefKind::Const { is_host_effect: true, .. }))
             })
             .count();
 
@@ -435,3 +422,73 @@ impl<'tcx> GenericPredicates<'tcx> {
         instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
     }
 }
+
+/// `~const` bounds for a given item. This is represented using a struct much like
+/// `GenericPredicates`, where you can either choose to only instantiate the "own"
+/// bounds or all of the bounds including those from the parent. This distinction
+/// is necessary for code like `compare_method_predicate_entailment`.
+#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
+pub struct ConstConditions<'tcx> {
+    pub parent: Option<DefId>,
+    pub predicates: &'tcx [(ty::PolyTraitRef<'tcx>, Span)],
+}
+
+impl<'tcx> ConstConditions<'tcx> {
+    pub fn instantiate(
+        self,
+        tcx: TyCtxt<'tcx>,
+        args: GenericArgsRef<'tcx>,
+    ) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
+        let mut instantiated = vec![];
+        self.instantiate_into(tcx, &mut instantiated, args);
+        instantiated
+    }
+
+    pub fn instantiate_own(
+        self,
+        tcx: TyCtxt<'tcx>,
+        args: GenericArgsRef<'tcx>,
+    ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
+    {
+        EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
+    }
+
+    pub fn instantiate_own_identity(
+        self,
+    ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
+    {
+        EarlyBinder::bind(self.predicates).iter_identity_copied()
+    }
+
+    #[instrument(level = "debug", skip(self, tcx))]
+    fn instantiate_into(
+        self,
+        tcx: TyCtxt<'tcx>,
+        instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>,
+        args: GenericArgsRef<'tcx>,
+    ) {
+        if let Some(def_id) = self.parent {
+            tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args);
+        }
+        instantiated.extend(
+            self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)),
+        );
+    }
+
+    pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
+        let mut instantiated = vec![];
+        self.instantiate_identity_into(tcx, &mut instantiated);
+        instantiated
+    }
+
+    fn instantiate_identity_into(
+        self,
+        tcx: TyCtxt<'tcx>,
+        instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>,
+    ) {
+        if let Some(def_id) = self.parent {
+            tcx.const_conditions(def_id).instantiate_identity_into(tcx, instantiated);
+        }
+        instantiated.extend(self.predicates.iter().copied());
+    }
+}
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index b1c5ff50fdc..61cb4322501 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -476,7 +476,6 @@ impl<'tcx> Instance<'tcx> {
     pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
         let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
             ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
-            ty::GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(),
             ty::GenericParamDefKind::Type { .. } => {
                 bug!("Instance::mono: {:?} has type parameters", def_id)
             }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ed24fcc7eb8..85414764817 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -84,12 +84,13 @@ pub use self::parameterized::ParameterizedOverTcx;
 pub use self::pattern::{Pattern, PatternKind};
 pub use self::predicate::{
     AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
-    ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo,
-    OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
-    PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate,
-    PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate,
-    PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef,
-    TraitPredicate, TraitRef, TypeOutlivesPredicate,
+    ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef,
+    HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate,
+    PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef,
+    PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate,
+    PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate,
+    RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef,
+    TypeOutlivesPredicate,
 };
 pub use self::region::BoundRegionKind::*;
 pub use self::region::{
@@ -1998,10 +1999,75 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
         matches!(
             self.def_kind(def_id),
-            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure
+            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure
         ) && self.constness(def_id) == hir::Constness::Const
     }
 
+    /// Whether this item is conditionally constant for the purposes of the
+    /// effects implementation.
+    ///
+    /// This roughly corresponds to all const functions and other callable
+    /// items, along with const impls and traits, and associated types within
+    /// those impls and traits.
+    pub fn is_conditionally_const(self, def_id: impl Into<DefId>) -> bool {
+        let def_id: DefId = def_id.into();
+        match self.def_kind(def_id) {
+            DefKind::Impl { of_trait: true } => {
+                self.constness(def_id) == hir::Constness::Const
+                    && self.is_const_trait(
+                        self.trait_id_of_impl(def_id)
+                            .expect("expected trait for trait implementation"),
+                    )
+            }
+            DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
+                self.constness(def_id) == hir::Constness::Const
+            }
+            DefKind::Trait => self.is_const_trait(def_id),
+            DefKind::AssocTy | DefKind::AssocFn => {
+                let parent_def_id = self.parent(def_id);
+                match self.def_kind(parent_def_id) {
+                    DefKind::Impl { of_trait: false } => {
+                        self.constness(def_id) == hir::Constness::Const
+                    }
+                    DefKind::Impl { of_trait: true } | DefKind::Trait => {
+                        self.is_conditionally_const(parent_def_id)
+                    }
+                    _ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
+                }
+            }
+            DefKind::Closure | DefKind::OpaqueTy => {
+                // Closures and RPITs will eventually have const conditions
+                // for `~const` bounds.
+                false
+            }
+            DefKind::Ctor(_, CtorKind::Const)
+            | DefKind::Impl { of_trait: false }
+            | DefKind::Mod
+            | DefKind::Struct
+            | DefKind::Union
+            | DefKind::Enum
+            | DefKind::Variant
+            | DefKind::TyAlias
+            | DefKind::ForeignTy
+            | DefKind::TraitAlias
+            | DefKind::TyParam
+            | DefKind::Const
+            | DefKind::ConstParam
+            | DefKind::Static { .. }
+            | DefKind::AssocConst
+            | DefKind::Macro(_)
+            | DefKind::ExternCrate
+            | DefKind::Use
+            | DefKind::ForeignMod
+            | DefKind::AnonConst
+            | DefKind::InlineConst
+            | DefKind::Field
+            | DefKind::LifetimeParam
+            | DefKind::GlobalAsm
+            | DefKind::SyntheticCoroutineBody => false,
+        }
+    }
+
     #[inline]
     pub fn is_const_trait(self, def_id: DefId) -> bool {
         self.trait_def(def_id).constness == hir::Constness::Const
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 7e1255f606c..43bdce5b576 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -132,6 +132,7 @@ parameterized_over_tcx! {
     ty::Ty,
     ty::FnSig,
     ty::GenericPredicates,
+    ty::ConstConditions,
     ty::TraitRef,
     ty::Const,
     ty::Predicate,
diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs
index d20cb368278..3ecaa3e22d3 100644
--- a/compiler/rustc_middle/src/ty/predicate.rs
+++ b/compiler/rustc_middle/src/ty/predicate.rs
@@ -19,6 +19,7 @@ pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
 pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
 pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
 pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>;
+pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate<TyCtxt<'tcx>>;
 pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
 pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
 pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
@@ -143,6 +144,7 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::AliasRelate(..)
             | PredicateKind::NormalizesTo(..) => false,
             PredicateKind::Clause(ClauseKind::Trait(_))
+            | PredicateKind::Clause(ClauseKind::HostEffect(..))
             | PredicateKind::Clause(ClauseKind::RegionOutlives(_))
             | PredicateKind::Clause(ClauseKind::TypeOutlives(_))
             | PredicateKind::Clause(ClauseKind::Projection(_))
@@ -644,6 +646,7 @@ impl<'tcx> Predicate<'tcx> {
         match predicate.skip_binder() {
             PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
             PredicateKind::Clause(ClauseKind::Projection(..))
+            | PredicateKind::Clause(ClauseKind::HostEffect(..))
             | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
             | PredicateKind::NormalizesTo(..)
             | PredicateKind::AliasRelate(..)
@@ -664,6 +667,7 @@ impl<'tcx> Predicate<'tcx> {
         match predicate.skip_binder() {
             PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
             PredicateKind::Clause(ClauseKind::Trait(..))
+            | PredicateKind::Clause(ClauseKind::HostEffect(..))
             | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
             | PredicateKind::NormalizesTo(..)
             | PredicateKind::AliasRelate(..)
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 10c3522eb0e..0248aad53e2 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -3075,6 +3075,15 @@ define_print! {
         p!(print(self.trait_ref.print_trait_sugared()))
     }
 
+    ty::HostEffectPredicate<'tcx> {
+        let constness = match self.host {
+            ty::HostPolarity::Const => { "const" }
+            ty::HostPolarity::Maybe => { "~const" }
+        };
+        p!(print(self.trait_ref.self_ty()), ": {constness} ");
+        p!(print(self.trait_ref.print_trait_sugared()))
+    }
+
     ty::TypeAndMut<'tcx> {
         p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
     }
@@ -3087,6 +3096,7 @@ define_print! {
             ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
             ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
             ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
+            ty::ClauseKind::HostEffect(predicate) => p!(print(predicate)),
             ty::ClauseKind::ConstArgHasType(ct, ty) => {
                 p!("the constant `", print(ct), "` has type `", print(ty), "`")
             },
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 06cbb6c9f1d..7fd7e463acf 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -17,10 +17,10 @@ use rustc_span::sym;
 use rustc_target::abi::{Float, Integer, IntegerType, Size};
 use rustc_target::spec::abi::Abi;
 use smallvec::{SmallVec, smallvec};
-use tracing::{debug, instrument, trace};
+use tracing::{debug, instrument};
 
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use crate::query::{IntoQueryParam, Providers};
+use crate::query::Providers;
 use crate::ty::layout::{FloatExt, IntegerExt};
 use crate::ty::{
     self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
@@ -865,48 +865,6 @@ impl<'tcx> TyCtxt<'tcx> {
             || self.extern_crate(key).is_some_and(|e| e.is_direct())
     }
 
-    /// Whether the item has a host effect param. This is different from `TyCtxt::is_const`,
-    /// because the item must also be "maybe const", and the crate where the item is
-    /// defined must also have the effects feature enabled.
-    pub fn has_host_param(self, def_id: impl IntoQueryParam<DefId>) -> bool {
-        self.generics_of(def_id).host_effect_index.is_some()
-    }
-
-    pub fn expected_host_effect_param_for_body(self, def_id: impl Into<DefId>) -> ty::Const<'tcx> {
-        let def_id = def_id.into();
-        // FIXME(effects): This is suspicious and should probably not be done,
-        // especially now that we enforce host effects and then properly handle
-        // effect vars during fallback.
-        let mut host_always_on = !self.features().effects()
-            || self.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
-
-        // Compute the constness required by the context.
-        let const_context = self.hir().body_const_context(def_id);
-
-        let kind = self.def_kind(def_id);
-        debug_assert_ne!(kind, DefKind::ConstParam);
-
-        if self.has_attr(def_id, sym::rustc_do_not_const_check) {
-            trace!("do not const check this context");
-            host_always_on = true;
-        }
-
-        match const_context {
-            _ if host_always_on => self.consts.true_,
-            Some(hir::ConstContext::Static(_) | hir::ConstContext::Const { .. }) => {
-                self.consts.false_
-            }
-            Some(hir::ConstContext::ConstFn) => {
-                let host_idx = self
-                    .generics_of(def_id)
-                    .host_effect_index
-                    .expect("ConstContext::Maybe must have host effect param");
-                ty::GenericArgs::identity_for_item(self, def_id).const_at(host_idx)
-            }
-            None => self.consts.true_,
-        }
-    }
-
     /// Expand any [weak alias types][weak] contained within the given `value`.
     ///
     /// This should be used over other normalization routines in situations where
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index b4d084d4dff..e5c59d60822 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1522,7 +1522,6 @@ fn create_mono_items_for_default_impls<'tcx>(
     // it, to validate whether or not the impl is legal to instantiate at all.
     let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind {
         GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
-        GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(),
         GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
             unreachable!(
                 "`own_requires_monomorphization` check means that \
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 23634d35c07..63608f9e856 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -431,7 +431,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
                     );
                     CanonicalVarKind::Const(self.delegate.universe_of_ct(vid).unwrap())
                 }
-                ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
                 ty::InferConst::Fresh(_) => todo!(),
             },
             ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs
index f2654f7534e..71c87714745 100644
--- a/compiler/rustc_next_trait_solver/src/resolve.rs
+++ b/compiler/rustc_next_trait_solver/src/resolve.rs
@@ -76,9 +76,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerResolv
                     resolved
                 }
             }
-            ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
-                self.delegate.opportunistic_resolve_effect_var(vid)
-            }
             _ => {
                 if c.has_infer() {
                     c.super_fold_with(self)
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index c9c0d6391fc..5e604a5d74f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -270,11 +270,6 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
     ) -> Vec<Candidate<I>>;
-
-    fn consider_builtin_effects_intersection_candidate(
-        ecx: &mut EvalCtxt<'_, D>,
-        goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution>;
 }
 
 impl<D, I> EvalCtxt<'_, D>
@@ -481,9 +476,6 @@ where
                 Some(TraitSolverLangItem::TransmuteTrait) => {
                     G::consider_builtin_transmute_candidate(self, goal)
                 }
-                Some(TraitSolverLangItem::EffectsIntersection) => {
-                    G::consider_builtin_effects_intersection_candidate(self, goal)
-                }
                 _ => Err(NoSolution),
             }
         };
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
new file mode 100644
index 00000000000..62b4bb0004c
--- /dev/null
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -0,0 +1,296 @@
+//! Dealing with host effect goals, i.e. enforcing the constness in
+//! `T: const Trait` or `T: ~const Trait`.
+
+use rustc_type_ir::fast_reject::DeepRejectCtxt;
+use rustc_type_ir::inherent::*;
+use rustc_type_ir::{self as ty, Interner};
+use tracing::instrument;
+
+use super::assembly::Candidate;
+use crate::delegate::SolverDelegate;
+use crate::solve::assembly::{self};
+use crate::solve::{
+    BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution,
+    QueryResult,
+};
+
+impl<D, I> assembly::GoalKind<D> for ty::HostEffectPredicate<I>
+where
+    D: SolverDelegate<Interner = I>,
+    I: Interner,
+{
+    fn self_ty(self) -> I::Ty {
+        self.self_ty()
+    }
+
+    fn trait_ref(self, _: I) -> ty::TraitRef<I> {
+        self.trait_ref
+    }
+
+    fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
+        self.with_self_ty(cx, self_ty)
+    }
+
+    fn trait_def_id(self, _: I) -> I::DefId {
+        self.def_id()
+    }
+
+    fn probe_and_match_goal_against_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        source: rustc_type_ir::solve::CandidateSource<I>,
+        goal: Goal<I, Self>,
+        assumption: <I as Interner>::Clause,
+        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        if let Some(host_clause) = assumption.as_host_effect_clause() {
+            if host_clause.def_id() == goal.predicate.def_id()
+                && host_clause.host().satisfies(goal.predicate.host)
+            {
+                if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                    goal.predicate.trait_ref.args,
+                    host_clause.skip_binder().trait_ref.args,
+                ) {
+                    return Err(NoSolution);
+                }
+
+                ecx.probe_trait_candidate(source).enter(|ecx| {
+                    let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
+                    ecx.eq(
+                        goal.param_env,
+                        goal.predicate.trait_ref,
+                        assumption_trait_pred.trait_ref,
+                    )?;
+                    then(ecx)
+                })
+            } else {
+                Err(NoSolution)
+            }
+        } else {
+            Err(NoSolution)
+        }
+    }
+
+    fn consider_impl_candidate(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        impl_def_id: <I as Interner>::DefId,
+    ) -> Result<Candidate<I>, NoSolution> {
+        let cx = ecx.cx();
+
+        let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
+        if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
+            .args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args)
+        {
+            return Err(NoSolution);
+        }
+
+        let impl_polarity = cx.impl_polarity(impl_def_id);
+        match impl_polarity {
+            ty::ImplPolarity::Negative => return Err(NoSolution),
+            ty::ImplPolarity::Reservation => {
+                unimplemented!("reservation impl for const trait: {:?}", goal)
+            }
+            ty::ImplPolarity::Positive => {}
+        };
+
+        if !cx.is_const_impl(impl_def_id) {
+            return Err(NoSolution);
+        }
+
+        ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
+            let impl_args = ecx.fresh_args_for_item(impl_def_id);
+            ecx.record_impl_args(impl_args);
+            let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args);
+
+            ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
+            let where_clause_bounds = cx
+                .predicates_of(impl_def_id)
+                .iter_instantiated(cx, impl_args)
+                .map(|pred| goal.with(cx, pred));
+            ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
+
+            // For this impl to be `const`, we need to check its `~const` bounds too.
+            let const_conditions = cx
+                .const_conditions(impl_def_id)
+                .iter_instantiated(cx, impl_args)
+                .map(|bound_trait_ref| {
+                    goal.with(cx, bound_trait_ref.to_host_effect_clause(cx, goal.predicate.host))
+                });
+            ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);
+
+            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        })
+    }
+
+    fn consider_error_guaranteed_candidate(
+        ecx: &mut EvalCtxt<'_, D>,
+        _guar: <I as Interner>::ErrorGuaranteed,
+    ) -> Result<Candidate<I>, NoSolution> {
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
+    }
+
+    fn consider_auto_trait_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("auto traits are never const")
+    }
+
+    fn consider_trait_alias_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("trait aliases are never const")
+    }
+
+    fn consider_builtin_sized_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("Sized is never const")
+    }
+
+    fn consider_builtin_copy_clone_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        todo!("Copy/Clone is not yet const")
+    }
+
+    fn consider_builtin_pointer_like_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("PointerLike is not const")
+    }
+
+    fn consider_builtin_fn_ptr_trait_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        todo!("Fn* are not yet const")
+    }
+
+    fn consider_builtin_fn_trait_candidates(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+        _kind: rustc_type_ir::ClosureKind,
+    ) -> Result<Candidate<I>, NoSolution> {
+        todo!("Fn* are not yet const")
+    }
+
+    fn consider_builtin_async_fn_trait_candidates(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+        _kind: rustc_type_ir::ClosureKind,
+    ) -> Result<Candidate<I>, NoSolution> {
+        todo!("AsyncFn* are not yet const")
+    }
+
+    fn consider_builtin_async_fn_kind_helper_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("AsyncFnKindHelper is not const")
+    }
+
+    fn consider_builtin_tuple_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("Tuple trait is not const")
+    }
+
+    fn consider_builtin_pointee_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("Pointee is not const")
+    }
+
+    fn consider_builtin_future_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("Future is not const")
+    }
+
+    fn consider_builtin_iterator_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        todo!("Iterator is not yet const")
+    }
+
+    fn consider_builtin_fused_iterator_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("FusedIterator is not const")
+    }
+
+    fn consider_builtin_async_iterator_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("AsyncIterator is not const")
+    }
+
+    fn consider_builtin_coroutine_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("Coroutine is not const")
+    }
+
+    fn consider_builtin_discriminant_kind_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("DiscriminantKind is not const")
+    }
+
+    fn consider_builtin_async_destruct_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("AsyncDestruct is not const")
+    }
+
+    fn consider_builtin_destruct_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("Destruct is not const")
+    }
+
+    fn consider_builtin_transmute_candidate(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        unreachable!("TransmuteFrom is not const")
+    }
+
+    fn consider_structural_builtin_unsize_candidates(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+    ) -> Vec<Candidate<I>> {
+        unreachable!("Unsize is not const")
+    }
+}
+
+impl<D, I> EvalCtxt<'_, D>
+where
+    D: SolverDelegate<Interner = I>,
+    I: Interner,
+{
+    #[instrument(level = "trace", skip(self))]
+    pub(super) fn compute_host_effect_goal(
+        &mut self,
+        goal: Goal<I, ty::HostEffectPredicate<I>>,
+    ) -> QueryResult<I> {
+        let candidates = self.assemble_and_evaluate_candidates(goal);
+        self.merge_candidates(candidates)
+    }
+}
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 250174e033e..7608253882a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -443,6 +443,9 @@ where
                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
                     self.compute_trait_goal(Goal { param_env, predicate })
                 }
+                ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
+                    self.compute_host_effect_goal(Goal { param_env, predicate })
+                }
                 ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
                     self.compute_projection_goal(Goal { param_env, predicate })
                 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index a475a58e483..6793779b205 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -13,6 +13,7 @@
 
 mod alias_relate;
 mod assembly;
+mod effect_goals;
 mod eval_ctxt;
 pub mod inspect;
 mod normalizes_to;
@@ -182,12 +183,6 @@ where
         let (ct, ty) = goal.predicate;
 
         let ct_ty = match ct.kind() {
-            // FIXME: Ignore effect vars because canonicalization doesn't handle them correctly
-            // and if we stall on the var then we wind up creating ambiguity errors in a probe
-            // for this goal which contains an effect var. Which then ends up ICEing.
-            ty::ConstKind::Infer(ty::InferConst::EffectVar(_)) => {
-                return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
-            }
             ty::ConstKind::Infer(_) => {
                 return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
             }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 4d8b193ee49..c98fd853551 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -911,68 +911,6 @@ where
     ) -> Result<Candidate<I>, NoSolution> {
         panic!("`TransmuteFrom` does not have an associated type: {:?}", goal)
     }
-
-    fn consider_builtin_effects_intersection_candidate(
-        ecx: &mut EvalCtxt<'_, D>,
-        goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution> {
-        let ty::Tuple(types) = goal.predicate.self_ty().kind() else {
-            return Err(NoSolution);
-        };
-
-        let cx = ecx.cx();
-
-        let mut first_non_maybe = None;
-        let mut non_maybe_count = 0;
-        for ty in types.iter() {
-            if !matches!(ty::EffectKind::try_from_ty(cx, ty), Some(ty::EffectKind::Maybe)) {
-                first_non_maybe.get_or_insert(ty);
-                non_maybe_count += 1;
-            }
-        }
-
-        match non_maybe_count {
-            0 => {
-                let ty = ty::EffectKind::Maybe.to_ty(cx);
-                ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
-                    ecx.instantiate_normalizes_to_term(goal, ty.into());
-                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-                })
-            }
-            1 => {
-                let ty = first_non_maybe.unwrap();
-                ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
-                    ecx.instantiate_normalizes_to_term(goal, ty.into());
-                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-                })
-            }
-            _ => {
-                let mut min = ty::EffectKind::Maybe;
-
-                for ty in types.iter() {
-                    // We can't find the intersection if the types used are generic.
-                    //
-                    // FIXME(effects): do we want to look at where clauses to get some
-                    // clue for the case where generic types are being used?
-                    let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else {
-                        return Err(NoSolution);
-                    };
-
-                    let Some(result) = ty::EffectKind::intersection(min, kind) else {
-                        return Err(NoSolution);
-                    };
-
-                    min = result;
-                }
-
-                let ty = min.to_ty(cx);
-                ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
-                    ecx.instantiate_normalizes_to_term(goal, ty.into());
-                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-                })
-            }
-        }
-    }
 }
 
 impl<D, I> EvalCtxt<'_, D>
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index a8d6536baad..6b26f960286 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -719,47 +719,6 @@ where
             }
         })
     }
-
-    fn consider_builtin_effects_intersection_candidate(
-        ecx: &mut EvalCtxt<'_, D>,
-        goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution> {
-        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
-            return Err(NoSolution);
-        }
-
-        let ty::Tuple(types) = goal.predicate.self_ty().kind() else {
-            return Err(NoSolution);
-        };
-
-        let cx = ecx.cx();
-        let maybe_count = types
-            .iter()
-            .filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty))
-            .filter(|&ty| ty == ty::EffectKind::Maybe)
-            .count();
-
-        // Don't do concrete type check unless there are more than one type that will influence the result.
-        // This would allow `(Maybe, T): Min` pass even if we know nothing about `T`.
-        if types.len() - maybe_count > 1 {
-            let mut min = ty::EffectKind::Maybe;
-
-            for ty in types.iter() {
-                let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else {
-                    return Err(NoSolution);
-                };
-
-                let Some(result) = ty::EffectKind::intersection(min, kind) else {
-                    return Err(NoSolution);
-                };
-
-                min = result;
-            }
-        }
-
-        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
-            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
-    }
 }
 
 impl<D, I> EvalCtxt<'_, D>
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 7827975d3ca..05954143aee 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -137,6 +137,10 @@ where
             ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
                 self.visit_trait(trait_ref)
             }
+            ty::ClauseKind::HostEffect(pred) => {
+                try_visit!(self.visit_trait(pred.trait_ref));
+                pred.host.visit_with(self)
+            }
             ty::ClauseKind::Projection(ty::ProjectionPredicate {
                 projection_term: projection_ty,
                 term,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index ef2ee9a166a..8f05f859c07 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -588,7 +588,6 @@ impl<'tcx> Stable<'tcx> for ty::Generics {
                 .has_late_bound_regions
                 .as_ref()
                 .map(|late_bound_regions| late_bound_regions.stable(tables)),
-            host_effect_index: self.host_effect_index,
         }
     }
 }
@@ -603,7 +602,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
             ty::GenericParamDefKind::Type { has_default, synthetic } => {
                 GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
             }
-            ty::GenericParamDefKind::Const { has_default, is_host_effect: _, synthetic: _ } => {
+            ty::GenericParamDefKind::Const { has_default, synthetic: _ } => {
                 GenericParamDefKind::Const { has_default: *has_default }
             }
         }
@@ -690,6 +689,9 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
             ClauseKind::ConstEvaluatable(const_) => {
                 stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
             }
+            ClauseKind::HostEffect(..) => {
+                todo!()
+            }
         }
     }
 }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index aa05b88ea0c..bf5f948fe91 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -195,14 +195,6 @@ symbols! {
         Display,
         DoubleEndedIterator,
         Duration,
-        EffectsCompat,
-        EffectsIntersection,
-        EffectsIntersectionOutput,
-        EffectsMaybe,
-        EffectsNoRuntime,
-        EffectsRuntime,
-        EffectsTyCompat,
-        Effects__,
         Encodable,
         Encoder,
         Enumerate,
@@ -1737,7 +1729,6 @@ symbols! {
         rustc_reallocator,
         rustc_regions,
         rustc_reservation_impl,
-        rustc_runtime,
         rustc_safe_intrinsic,
         rustc_serialize,
         rustc_skip_during_method_dispatch,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 6ef64c3ed80..b7e2ed391cd 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -156,8 +156,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             (leaf_trait_predicate, &obligation)
                         };
 
-                        let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span);
-
                         let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
                         let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
 
@@ -228,7 +226,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let err_msg = self.get_standard_error_message(
                             main_trait_predicate,
                             message,
-                            predicate_constness,
+                            None,
                             append_const_msg,
                             post_message,
                         );
@@ -289,13 +287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             );
                         }
 
-                        if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
-                            && matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const))
-                        {
-                            err.note("`~const Drop` was renamed to `~const Destruct`");
-                            err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
-                        }
-
                         let explanation = get_explanation_based_on_obligation(
                             self.tcx,
                             &obligation,
@@ -541,6 +532,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         err
                     }
 
+                    ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
+                        // FIXME(effects): We should recompute the predicate with `~const`
+                        // if it's `const`, and if it holds, explain that this bound only
+                        // *conditionally* holds. If that fails, we should also do selection
+                        // to drill this down to an impl or built-in source, so we can
+                        // point at it and explain that while the trait *is* implemented,
+                        // that implementation is not const.
+                        let err_msg = self.get_standard_error_message(
+                            bound_predicate.rebind(ty::TraitPredicate {
+                                trait_ref: predicate.trait_ref,
+                                polarity: ty::PredicatePolarity::Positive,
+                            }),
+                            None,
+                            Some(match predicate.host {
+                                ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst,
+                                ty::HostPolarity::Const => ty::BoundConstness::Const,
+                            }),
+                            None,
+                            String::new(),
+                        );
+                        struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg)
+                    }
+
                     ty::PredicateKind::Subtype(predicate) => {
                         // Errors for Subtype predicates show up as
                         // `FulfillmentErrorCode::SubtypeError`,
@@ -2374,52 +2388,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         })
     }
 
-    /// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the
-    /// predicate that failed was `u32: Add`. Return the constness of such predicate to later
-    /// print as `u32: ~const Add`.
-    fn get_effects_trait_pred_override(
-        &self,
-        p: ty::PolyTraitPredicate<'tcx>,
-        leaf: ty::PolyTraitPredicate<'tcx>,
-        span: Span,
-    ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, Option<ty::BoundConstness>)
-    {
-        let trait_ref = p.to_poly_trait_ref();
-        if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) {
-            return (p, leaf, None);
-        }
-
-        let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) =
-            trait_ref.self_ty().no_bound_vars().map(Ty::kind)
-        else {
-            return (p, leaf, None);
-        };
-
-        let constness = trait_ref.skip_binder().args.const_at(1);
-
-        let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() {
-            None
-        } else if constness == self.tcx.consts.false_ {
-            Some(ty::BoundConstness::Const)
-        } else if matches!(constness.kind(), ty::ConstKind::Param(_)) {
-            Some(ty::BoundConstness::ConstIfConst)
-        } else {
-            self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}"));
-        };
-
-        let new_pred = p.map_bound(|mut trait_pred| {
-            trait_pred.trait_ref = projection.trait_ref(self.tcx);
-            trait_pred
-        });
-
-        let new_leaf = leaf.map_bound(|mut trait_pred| {
-            trait_pred.trait_ref = projection.trait_ref(self.tcx);
-            trait_pred
-        });
-
-        (new_pred, new_leaf, constness)
-    }
-
     fn add_tuple_trait_message(
         &self,
         obligation_cause_code: &ObligationCauseCode<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 12aeee0d02f..934fe9ec47c 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -806,7 +806,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                 | ty::PredicateKind::Subtype(..)
                 // FIXME(generic_const_exprs): you can absolutely add this as a where clauses
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
-                | ty::PredicateKind::Coerce(..) => {}
+                | ty::PredicateKind::Coerce(..)
+                | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {}
                 ty::PredicateKind::Ambiguous => return false,
             };
         }
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index cc0450e0b05..a068f25fe35 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -245,6 +245,7 @@ fn predicate_references_self<'tcx>(
         | ty::ClauseKind::RegionOutlives(..)
         // FIXME(generic_const_exprs): this can mention `Self`
         | ty::ClauseKind::ConstEvaluatable(..)
+        | ty::ClauseKind::HostEffect(..)
          => None,
     }
 }
@@ -284,7 +285,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         | ty::ClauseKind::Projection(_)
         | ty::ClauseKind::ConstArgHasType(_, _)
         | ty::ClauseKind::WellFormed(_)
-        | ty::ClauseKind::ConstEvaluatable(_) => false,
+        | ty::ClauseKind::ConstEvaluatable(_)
+        | ty::ClauseKind::HostEffect(..) => false,
     })
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 2bdeb00bdac..1754418156d 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -372,7 +372,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                 | ty::PredicateKind::Subtype(_)
                 | ty::PredicateKind::Coerce(_)
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
-                | ty::PredicateKind::ConstEquate(..) => {
+                | ty::PredicateKind::ConstEquate(..)
+                // FIXME(effects): We may need to do this using the higher-ranked
+                // pred instead of just instantiating it with placeholders b/c of
+                // higher-ranked implied bound issues in the old solver.
+                | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
                     let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
                     let mut obligations = PredicateObligations::with_capacity(1);
                     obligations.push(obligation.with(infcx.tcx, pred));
@@ -398,6 +402,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     )
                 }
 
+                ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
+                    ProcessResult::Changed(Default::default())
+                }
+
                 ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
                     if infcx.considering_regions {
                         infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
@@ -450,7 +458,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         ty::ConstKind::Infer(var) => {
                             let var = match var {
                                 ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid),
-                                ty::InferConst::EffectVar(vid) => TyOrConstInferVar::Effect(vid),
                                 ty::InferConst::Fresh(_) => {
                                     bug!("encountered fresh const in fulfill")
                                 }
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index dfd0cab6905..c6e41e57f0c 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -96,6 +96,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
                 // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
                 // if we ever support that
                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
+                | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
                 | ty::PredicateKind::Subtype(..)
                 | ty::PredicateKind::Coerce(..)
@@ -200,6 +201,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
                 // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
                 // if we ever support that
                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
+                | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
                 | ty::PredicateKind::Subtype(..)
                 | ty::PredicateKind::Coerce(..)
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c0122d3d552..47601b0c18d 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -546,7 +546,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             }
             // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
-            ty::FnDef(def_id, _args) => {
+            ty::FnDef(def_id, _) => {
                 let tcx = self.tcx();
                 if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
                     && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index d5b1c5a97da..ec4114fd9d7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -645,6 +645,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     self.evaluate_trait_predicate_recursively(previous_stack, obligation)
                 }
 
+                ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
+                    // FIXME(effects): It should be relatively straightforward to implement
+                    // old trait solver support for `HostEffect` bounds; or at least basic
+                    // support for them.
+                    todo!()
+                }
+
                 ty::PredicateKind::Subtype(p) => {
                     let p = bound_predicate.rebind(p);
                     // Does this code ever run?
@@ -1821,8 +1828,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             |cand: ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars();
 
         // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
-        // `DiscriminantKindCandidate`, `ConstDestructCandidate`
-        // to anything else.
+        // or `DiscriminantKindCandidate` to anything else.
         //
         // This is a fix for #53123 and prevents winnowing from accidentally extending the
         // lifetime of a variable.
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 8904a9a6858..437343b569c 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -170,6 +170,10 @@ pub fn clause_obligations<'tcx>(
         ty::ClauseKind::Trait(t) => {
             wf.compute_trait_pred(t, Elaborate::None);
         }
+        ty::ClauseKind::HostEffect(..) => {
+            // Technically the well-formedness of this predicate is implied by
+            // the corresponding trait predicate it should've been generated beside.
+        }
         ty::ClauseKind::RegionOutlives(..) => {}
         ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
             wf.compute(ty.into());
@@ -1021,6 +1025,7 @@ pub(crate) fn required_region_bounds<'tcx>(
                     }
                 }
                 ty::ClauseKind::Trait(_)
+                | ty::ClauseKind::HostEffect(..)
                 | ty::ClauseKind::RegionOutlives(_)
                 | ty::ClauseKind::Projection(_)
                 | ty::ClauseKind::ConstArgHasType(_, _)
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index f01a12b0a00..3e2794f6489 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -55,6 +55,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool {
         | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => false,
         ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
         | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
+        | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
         | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
         | ty::PredicateKind::NormalizesTo(..)
         | ty::PredicateKind::AliasRelate(..)
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index a3210dd80d7..16fd28201c2 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -4,9 +4,8 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt};
+use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
 use rustc_middle::{bug, span_bug};
-use rustc_span::sym;
 use rustc_span::symbol::kw;
 
 pub(crate) fn provide(providers: &mut Providers) {
@@ -15,7 +14,6 @@ pub(crate) fn provide(providers: &mut Providers) {
         associated_item_def_ids,
         associated_items,
         associated_types_for_impl_traits_in_associated_fn,
-        associated_type_for_effects,
         associated_type_for_impl_trait_in_trait,
         impl_item_implementor_ids,
         ..*providers
@@ -46,8 +44,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
                                 )
                             })
                             .copied(),
-                    )
-                    .chain(tcx.associated_type_for_effects(def_id)),
+                    ),
             )
         }
         hir::ItemKind::Impl(impl_) => {
@@ -73,8 +70,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
                                 )
                             })
                             .copied()
-                    }))
-                    .chain(tcx.associated_type_for_effects(def_id)),
+                    })),
             )
         }
         _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
@@ -171,134 +167,6 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
     }
 }
 
-/// Given an `def_id` of a trait or a trait impl:
-///
-/// If `def_id` is a trait that has `#[const_trait]`, then it synthesizes
-/// a new def id corresponding to a new associated type for the effects.
-///
-/// If `def_id` is an impl, then synthesize the associated type according
-/// to the constness of the impl.
-fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
-    // don't synthesize the associated type even if the user has written `const_trait`
-    // if the effects feature is disabled.
-    if !tcx.features().effects() {
-        return None;
-    }
-    let (feed, parent_did) = match tcx.def_kind(def_id) {
-        DefKind::Trait => {
-            let trait_def_id = def_id;
-            let attr = tcx.get_attr(def_id, sym::const_trait)?;
-
-            let span = attr.span;
-            let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy);
-
-            let local_def_id = trait_assoc_ty.def_id();
-            let def_id = local_def_id.to_def_id();
-
-            // Copy span of the attribute.
-            trait_assoc_ty.def_ident_span(Some(span));
-
-            trait_assoc_ty.associated_item(ty::AssocItem {
-                name: kw::Empty,
-                kind: ty::AssocKind::Type,
-                def_id,
-                trait_item_def_id: None,
-                container: ty::TraitContainer,
-                fn_has_self_parameter: false,
-                opt_rpitit_info: None,
-                is_effects_desugaring: true,
-            });
-
-            // No default type
-            trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false });
-
-            trait_assoc_ty.is_type_alias_impl_trait(false);
-
-            (trait_assoc_ty, trait_def_id)
-        }
-        DefKind::Impl { .. } => {
-            let impl_def_id = def_id;
-            let trait_id = tcx.trait_id_of_impl(def_id.to_def_id())?;
-
-            // first get the DefId of the assoc type on the trait, if there is not,
-            // then we don't need to generate it on the impl.
-            let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?;
-
-            // FIXME(effects): span
-            let span = tcx.def_ident_span(def_id).unwrap();
-
-            let impl_assoc_ty = tcx.at(span).create_def(def_id, kw::Empty, DefKind::AssocTy);
-
-            let local_def_id = impl_assoc_ty.def_id();
-            let def_id = local_def_id.to_def_id();
-
-            impl_assoc_ty.def_ident_span(Some(span));
-
-            impl_assoc_ty.associated_item(ty::AssocItem {
-                name: kw::Empty,
-                kind: ty::AssocKind::Type,
-                def_id,
-                trait_item_def_id: Some(trait_assoc_id),
-                container: ty::ImplContainer,
-                fn_has_self_parameter: false,
-                opt_rpitit_info: None,
-                is_effects_desugaring: true,
-            });
-
-            // no default value.
-            impl_assoc_ty.defaultness(hir::Defaultness::Final);
-
-            // set the type of the associated type! If this is a const impl,
-            // we set to Maybe, otherwise we set to `Runtime`.
-            let type_def_id = if tcx.is_const_trait_impl_raw(impl_def_id.to_def_id()) {
-                tcx.require_lang_item(hir::LangItem::EffectsMaybe, Some(span))
-            } else {
-                tcx.require_lang_item(hir::LangItem::EffectsRuntime, Some(span))
-            };
-            // FIXME(effects): make impls use `Min` for their effect types
-            impl_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_adt(
-                tcx,
-                tcx.adt_def(type_def_id),
-                ty::GenericArgs::empty(),
-            )));
-
-            (impl_assoc_ty, impl_def_id)
-        }
-        def_kind => bug!(
-            "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}",
-            def_id,
-            def_kind
-        ),
-    };
-
-    feed.feed_hir();
-
-    // visibility is public.
-    feed.visibility(ty::Visibility::Public);
-
-    // Copy generics_of of the trait/impl, making the trait/impl as parent.
-    feed.generics_of({
-        let parent_generics = tcx.generics_of(parent_did);
-        let parent_count = parent_generics.parent_count + parent_generics.own_params.len();
-
-        ty::Generics {
-            parent: Some(parent_did.to_def_id()),
-            parent_count,
-            own_params: vec![],
-            param_def_id_to_index: parent_generics.param_def_id_to_index.clone(),
-            has_self: false,
-            has_late_bound_regions: None,
-            host_effect_index: parent_generics.host_effect_index,
-        }
-    });
-    feed.explicit_item_super_predicates(ty::EarlyBinder::bind(&[]));
-
-    // There are no inferred outlives for the synthesized associated type.
-    feed.inferred_outlives_of(&[]);
-
-    Some(feed.def_id().to_def_id())
-}
-
 /// Given an `fn_def_id` of a trait or a trait implementation:
 ///
 /// if `fn_def_id` is a function defined inside a trait, then it synthesizes
@@ -494,7 +362,6 @@ fn associated_type_for_impl_trait_in_impl(
             param_def_id_to_index,
             has_self: false,
             has_late_bound_regions: trait_assoc_generics.has_late_bound_regions,
-            host_effect_index: parent_generics.host_effect_index,
         }
     });
 
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 28a81b1b062..aa499995bcb 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -150,6 +150,16 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
         });
     }
 
+    // We extend the param-env of our item with the const conditions of the item,
+    // since we're allowed to assume `~const` bounds hold within the item itself.
+    if tcx.is_conditionally_const(def_id) {
+        predicates.extend(
+            tcx.const_conditions(def_id).instantiate_identity(tcx).into_iter().map(
+                |(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
+            ),
+        );
+    }
+
     let local_did = def_id.as_local();
 
     let unnormalized_env =
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 07cb8b037ec..3fb7d87bcc4 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -108,7 +108,6 @@ impl<I: Interner> CanonicalVarInfo<I> {
             CanonicalVarKind::PlaceholderRegion(..) => false,
             CanonicalVarKind::Const(_) => true,
             CanonicalVarKind::PlaceholderConst(_) => false,
-            CanonicalVarKind::Effect => true,
         }
     }
 
@@ -118,17 +117,15 @@ impl<I: Interner> CanonicalVarInfo<I> {
             CanonicalVarKind::Ty(_)
             | CanonicalVarKind::PlaceholderTy(_)
             | CanonicalVarKind::Const(_)
-            | CanonicalVarKind::PlaceholderConst(_)
-            | CanonicalVarKind::Effect => false,
+            | CanonicalVarKind::PlaceholderConst(_) => false,
         }
     }
 
     pub fn expect_placeholder_index(self) -> usize {
         match self.kind {
-            CanonicalVarKind::Ty(_)
-            | CanonicalVarKind::Region(_)
-            | CanonicalVarKind::Const(_)
-            | CanonicalVarKind::Effect => panic!("expected placeholder: {self:?}"),
+            CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) | CanonicalVarKind::Const(_) => {
+                panic!("expected placeholder: {self:?}")
+            }
 
             CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
             CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
@@ -161,9 +158,6 @@ pub enum CanonicalVarKind<I: Interner> {
     /// Some kind of const inference variable.
     Const(UniverseIndex),
 
-    /// Effect variable `'?E`.
-    Effect,
-
     /// A "placeholder" that represents "any const".
     PlaceholderConst(I::PlaceholderConst),
 }
@@ -180,7 +174,6 @@ impl<I: Interner> CanonicalVarKind<I> {
             CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
                 UniverseIndex::ROOT
             }
-            CanonicalVarKind::Effect => UniverseIndex::ROOT,
         }
     }
 
@@ -205,8 +198,7 @@ impl<I: Interner> CanonicalVarKind<I> {
             CanonicalVarKind::PlaceholderConst(placeholder) => {
                 CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
             }
-            CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
-            | CanonicalVarKind::Effect => {
+            CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
                 assert_eq!(ui, UniverseIndex::ROOT);
                 self
             }
@@ -311,10 +303,6 @@ impl<I: Interner> CanonicalVarValues<I> {
                             Region::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
                                 .into()
                         }
-                        CanonicalVarKind::Effect => {
-                            Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
-                                .into()
-                        }
                         CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => {
                             Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
                                 .into()
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs
index 7a8c612057f..03dfe547ced 100644
--- a/compiler/rustc_type_ir/src/const_kind.rs
+++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -84,32 +84,12 @@ rustc_index::newtype_index! {
     pub struct ConstVid {}
 }
 
-rustc_index::newtype_index! {
-    /// An **effect** **v**ariable **ID**.
-    ///
-    /// Handling effect infer variables happens separately from const infer variables
-    /// because we do not want to reuse any of the const infer machinery. If we try to
-    /// relate an effect variable with a normal one, we would ICE, which can catch bugs
-    /// where we are not correctly using the effect var for an effect param. Fallback
-    /// is also implemented on top of having separate effect and normal const variables.
-    #[encodable]
-    #[orderable]
-    #[debug_format = "?{}e"]
-    #[gate_rustc_only]
-    pub struct EffectVid {}
-}
-
 /// An inference variable for a const, for use in const generics.
 #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
 pub enum InferConst {
     /// Infer the value of the const.
     Var(ConstVid),
-    /// Infer the value of the effect.
-    ///
-    /// For why this is separate from the `Var` variant above, see the
-    /// documentation on `EffectVid`.
-    EffectVar(EffectVid),
     /// A fresh const variable. See `infer::freshen` for more details.
     Fresh(u32),
 }
@@ -118,7 +98,6 @@ impl fmt::Debug for InferConst {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             InferConst::Var(var) => write!(f, "{var:?}"),
-            InferConst::EffectVar(var) => write!(f, "{var:?}"),
             InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
         }
     }
@@ -128,7 +107,7 @@ impl fmt::Debug for InferConst {
 impl<CTX> HashStable<CTX> for InferConst {
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
         match self {
-            InferConst::Var(_) | InferConst::EffectVar(_) => {
+            InferConst::Var(_) => {
                 panic!("const variables should not be hashed: {self:?}")
             }
             InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs
deleted file mode 100644
index ab43533dd86..00000000000
--- a/compiler/rustc_type_ir/src/effects.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use crate::Interner;
-use crate::inherent::*;
-use crate::lang_items::TraitSolverLangItem::{EffectsMaybe, EffectsNoRuntime, EffectsRuntime};
-
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub enum EffectKind {
-    Maybe,
-    Runtime,
-    NoRuntime,
-}
-
-impl EffectKind {
-    pub fn try_from_def_id<I: Interner>(cx: I, def_id: I::DefId) -> Option<EffectKind> {
-        if cx.is_lang_item(def_id, EffectsMaybe) {
-            Some(EffectKind::Maybe)
-        } else if cx.is_lang_item(def_id, EffectsRuntime) {
-            Some(EffectKind::Runtime)
-        } else if cx.is_lang_item(def_id, EffectsNoRuntime) {
-            Some(EffectKind::NoRuntime)
-        } else {
-            None
-        }
-    }
-
-    pub fn to_def_id<I: Interner>(self, cx: I) -> I::DefId {
-        let lang_item = match self {
-            EffectKind::Maybe => EffectsMaybe,
-            EffectKind::NoRuntime => EffectsNoRuntime,
-            EffectKind::Runtime => EffectsRuntime,
-        };
-
-        cx.require_lang_item(lang_item)
-    }
-
-    pub fn try_from_ty<I: Interner>(cx: I, ty: I::Ty) -> Option<EffectKind> {
-        if let crate::Adt(def, _) = ty.kind() {
-            Self::try_from_def_id(cx, def.def_id())
-        } else {
-            None
-        }
-    }
-
-    pub fn to_ty<I: Interner>(self, cx: I) -> I::Ty {
-        I::Ty::new_adt(cx, cx.adt_def(self.to_def_id(cx)), Default::default())
-    }
-
-    /// Returns an intersection between two effect kinds. If one effect kind
-    /// is more permissive than the other (e.g. `Maybe` vs `Runtime`), this
-    /// returns the less permissive effect kind (`Runtime`).
-    pub fn intersection(a: Self, b: Self) -> Option<Self> {
-        use EffectKind::*;
-        match (a, b) {
-            (Maybe, x) | (x, Maybe) => Some(x),
-            (Runtime, Runtime) => Some(Runtime),
-            (NoRuntime, NoRuntime) => Some(NoRuntime),
-            (Runtime, NoRuntime) | (NoRuntime, Runtime) => None,
-        }
-    }
-}
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index dac45ff2aba..72d392ecd7b 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -4,7 +4,6 @@ use smallvec::smallvec;
 
 use crate::data_structures::HashSet;
 use crate::inherent::*;
-use crate::lang_items::TraitSolverLangItem;
 use crate::outlives::{Component, push_outlives_components};
 use crate::{self as ty, Interner, Upcast as _};
 
@@ -130,70 +129,6 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
                     return;
                 }
 
-                // HACK(effects): The following code is required to get implied bounds for effects associated
-                // types to work with super traits.
-                //
-                // Suppose `data` is a trait predicate with the form `<T as Tr>::Fx: EffectsCompat<somebool>`
-                // and we know that `trait Tr: ~const SuperTr`, we need to elaborate this predicate into
-                // `<T as SuperTr>::Fx: EffectsCompat<somebool>`.
-                //
-                // Since the semantics for elaborating bounds about effects is equivalent to elaborating
-                // bounds about super traits (elaborate `T: Tr` into `T: SuperTr`), we place effects elaboration
-                // next to super trait elaboration.
-                if cx.is_lang_item(data.def_id(), TraitSolverLangItem::EffectsCompat)
-                    && matches!(self.mode, Filter::All)
-                {
-                    // first, ensure that the predicate we've got looks like a `<T as Tr>::Fx: EffectsCompat<somebool>`.
-                    if let ty::Alias(ty::AliasTyKind::Projection, alias_ty) = data.self_ty().kind()
-                    {
-                        // look for effects-level bounds that look like `<Self as Tr>::Fx: TyCompat<<Self as SuperTr>::Fx>`
-                        // on the trait, which is proof to us that `Tr: ~const SuperTr`. We're looking for bounds on the
-                        // associated trait, so we use `explicit_implied_predicates_of` since it gives us more than just
-                        // `Self: SuperTr` bounds.
-                        let bounds = cx.explicit_implied_predicates_of(cx.parent(alias_ty.def_id));
-
-                        // instantiate the implied bounds, so we get `<T as Tr>::Fx` and not `<Self as Tr>::Fx`.
-                        let elaborated = bounds.iter_instantiated(cx, alias_ty.args).filter_map(
-                            |(clause, _)| {
-                                let ty::ClauseKind::Trait(tycompat_bound) =
-                                    clause.kind().skip_binder()
-                                else {
-                                    return None;
-                                };
-                                if !cx.is_lang_item(
-                                    tycompat_bound.def_id(),
-                                    TraitSolverLangItem::EffectsTyCompat,
-                                ) {
-                                    return None;
-                                }
-
-                                // extract `<T as SuperTr>::Fx` from the `TyCompat` bound.
-                                let supertrait_effects_ty =
-                                    tycompat_bound.trait_ref.args.type_at(1);
-                                let ty::Alias(ty::AliasTyKind::Projection, supertrait_alias_ty) =
-                                    supertrait_effects_ty.kind()
-                                else {
-                                    return None;
-                                };
-
-                                // The self types (`T`) must be equal for `<T as Tr>::Fx` and `<T as SuperTr>::Fx`.
-                                if supertrait_alias_ty.self_ty() != alias_ty.self_ty() {
-                                    return None;
-                                };
-
-                                // replace the self type in the original bound `<T as Tr>::Fx: EffectsCompat<somebool>`
-                                // to the effects type of the super trait. (`<T as SuperTr>::Fx`)
-                                let elaborated_bound = data.with_self_ty(cx, supertrait_effects_ty);
-                                Some(
-                                    elaboratable
-                                        .child(bound_clause.rebind(elaborated_bound).upcast(cx)),
-                                )
-                            },
-                        );
-                        self.extend_deduped(elaborated);
-                    }
-                }
-
                 let map_to_child_clause =
                     |(index, (clause, span)): (usize, (I::Clause, I::Span))| {
                         elaboratable.child_with_derived_cause(
@@ -220,6 +155,16 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
                     ),
                 };
             }
+            // `T: ~const Trait` implies `T: ~const Supertrait`.
+            ty::ClauseKind::HostEffect(data) => self.extend_deduped(
+                cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
+                    elaboratable.child(
+                        trait_ref
+                            .to_host_effect_clause(cx, data.host)
+                            .instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)),
+                    )
+                }),
+            ),
             ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
                 // We know that `T: 'a` for some type `T`. We can
                 // often elaborate this. For example, if we know that
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index b9f5cde653e..7c6a3c65ebf 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -38,10 +38,6 @@ pub trait InferCtxtLike: Sized {
         &self,
         vid: ty::ConstVid,
     ) -> <Self::Interner as Interner>::Const;
-    fn opportunistic_resolve_effect_var(
-        &self,
-        vid: ty::EffectVid,
-    ) -> <Self::Interner as Interner>::Const;
     fn opportunistic_resolve_lt_var(
         &self,
         vid: ty::RegionVid,
@@ -71,7 +67,6 @@ pub trait InferCtxtLike: Sized {
     fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid);
     fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid);
     fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid);
-    fn equate_effect_vids_raw(&self, a: ty::EffectVid, b: ty::EffectVid);
 
     fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
         &self,
@@ -83,11 +78,6 @@ pub trait InferCtxtLike: Sized {
     ) -> RelateResult<Self::Interner, ()>;
     fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue);
     fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue);
-    fn instantiate_effect_var_raw(
-        &self,
-        vid: ty::EffectVid,
-        value: <Self::Interner as Interner>::Const,
-    );
     fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
         &self,
         relation: &mut R,
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 02ec29a7f3d..5af1aa2f8fa 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -468,6 +468,14 @@ pub trait Clause<I: Interner<Clause = Self>>:
             .transpose()
     }
 
+    fn as_host_effect_clause(self) -> Option<ty::Binder<I, ty::HostEffectPredicate<I>>> {
+        self.kind()
+            .map_bound(
+                |clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None },
+            )
+            .transpose()
+    }
+
     fn as_projection_clause(self) -> Option<ty::Binder<I, ty::ProjectionPredicate<I>>> {
         self.kind()
             .map_bound(
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 4184e9e313f..6a8113b38b7 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -24,6 +24,7 @@ pub trait Interner:
     + IrPrint<ty::AliasTerm<Self>>
     + IrPrint<ty::TraitRef<Self>>
     + IrPrint<ty::TraitPredicate<Self>>
+    + IrPrint<ty::HostEffectPredicate<Self>>
     + IrPrint<ty::ExistentialTraitRef<Self>>
     + IrPrint<ty::ExistentialProjection<Self>>
     + IrPrint<ty::ProjectionPredicate<Self>>
@@ -228,6 +229,16 @@ pub trait Interner:
         def_id: Self::DefId,
     ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
 
+    fn is_const_impl(self, def_id: Self::DefId) -> bool;
+    fn const_conditions(
+        self,
+        def_id: Self::DefId,
+    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
+    fn implied_const_bounds(
+        self,
+        def_id: Self::DefId,
+    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
+
     fn has_target_features(self, def_id: Self::DefId) -> bool;
 
     fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId;
diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs
index d57d0816680..0c71f3a3df2 100644
--- a/compiler/rustc_type_ir/src/ir_print.rs
+++ b/compiler/rustc_type_ir/src/ir_print.rs
@@ -2,8 +2,8 @@ use std::fmt;
 
 use crate::{
     AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
-    Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate, SubtypePredicate,
-    TraitPredicate, TraitRef,
+    HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate,
+    SubtypePredicate, TraitPredicate, TraitRef,
 };
 
 pub trait IrPrint<T> {
@@ -53,6 +53,7 @@ define_display_via_print!(
     NormalizesTo,
     SubtypePredicate,
     CoercePredicate,
+    HostEffectPredicate,
     AliasTy,
     AliasTerm,
     FnSig,
diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs
index c680c844746..d6ca22a90a4 100644
--- a/compiler/rustc_type_ir/src/lang_items.rs
+++ b/compiler/rustc_type_ir/src/lang_items.rs
@@ -20,13 +20,6 @@ pub enum TraitSolverLangItem {
     Destruct,
     DiscriminantKind,
     DynMetadata,
-    EffectsCompat,
-    EffectsIntersection,
-    EffectsIntersectionOutput,
-    EffectsMaybe,
-    EffectsNoRuntime,
-    EffectsRuntime,
-    EffectsTyCompat,
     Fn,
     FnMut,
     FnOnce,
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 9e6d1f424ba..e7ca24178cb 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -43,7 +43,6 @@ mod macros;
 mod binder;
 mod canonical;
 mod const_kind;
-mod effects;
 mod flags;
 mod generic_arg;
 mod infer_ctxt;
@@ -67,7 +66,6 @@ pub use canonical::*;
 #[cfg(feature = "nightly")]
 pub use codec::*;
 pub use const_kind::*;
-pub use effects::*;
 pub use flags::*;
 pub use generic_arg::*;
 pub use infer_ctxt::*;
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index e8ce39be3e5..c3164550348 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -111,6 +111,13 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
     pub fn def_id(&self) -> I::DefId {
         self.skip_binder().def_id
     }
+
+    pub fn to_host_effect_clause(self, cx: I, host: HostPolarity) -> I::Clause {
+        self.map_bound(|trait_ref| {
+            ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, host })
+        })
+        .upcast(cx)
+    }
 }
 
 #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
@@ -745,6 +752,64 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> {
     }
 }
 
+#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
+#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
+#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
+pub struct HostEffectPredicate<I: Interner> {
+    pub trait_ref: ty::TraitRef<I>,
+    pub host: HostPolarity,
+}
+
+impl<I: Interner> HostEffectPredicate<I> {
+    pub fn self_ty(self) -> I::Ty {
+        self.trait_ref.self_ty()
+    }
+
+    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
+        Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
+    }
+
+    pub fn def_id(self) -> I::DefId {
+        self.trait_ref.def_id
+    }
+}
+
+impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
+    pub fn def_id(self) -> I::DefId {
+        // Ok to skip binder since trait `DefId` does not care about regions.
+        self.skip_binder().def_id()
+    }
+
+    pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
+        self.map_bound(|trait_ref| trait_ref.self_ty())
+    }
+
+    #[inline]
+    pub fn host(self) -> HostPolarity {
+        self.skip_binder().host
+    }
+}
+
+#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
+#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
+#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
+pub enum HostPolarity {
+    /// May be called in const environments if the callee is const.
+    Maybe,
+    /// Always allowed to be called in const environments.
+    Const,
+}
+
+impl HostPolarity {
+    pub fn satisfies(self, goal: HostPolarity) -> bool {
+        match (self, goal) {
+            (HostPolarity::Const, HostPolarity::Const | HostPolarity::Maybe) => true,
+            (HostPolarity::Maybe, HostPolarity::Maybe) => true,
+            (HostPolarity::Maybe, HostPolarity::Const) => false,
+        }
+    }
+}
+
 /// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
 /// whether the `a` type is the type that we should label as "expected" when
 /// presenting user diagnostics.
diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs
index 46202dbb0f2..21f4456abd1 100644
--- a/compiler/rustc_type_ir/src/predicate_kind.rs
+++ b/compiler/rustc_type_ir/src/predicate_kind.rs
@@ -37,6 +37,12 @@ pub enum ClauseKind<I: Interner> {
 
     /// Constant initializer must evaluate successfully.
     ConstEvaluatable(I::Const),
+
+    /// Enforces the constness of the predicate we're calling. Like a projection
+    /// goal from a where clause, it's always going to be paired with a
+    /// corresponding trait clause; this just enforces the *constness* of that
+    /// implementation.
+    HostEffect(ty::HostEffectPredicate<I>),
 }
 
 #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
@@ -110,6 +116,7 @@ impl<I: Interner> fmt::Debug for ClauseKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
+            ClauseKind::HostEffect(data) => data.fmt(f),
             ClauseKind::Trait(a) => a.fmt(f),
             ClauseKind::RegionOutlives(pair) => pair.fmt(f),
             ClauseKind::TypeOutlives(pair) => pair.fmt(f),
diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs
index 60a953801a4..17a3912730f 100644
--- a/compiler/rustc_type_ir/src/relate/combine.rs
+++ b/compiler/rustc_type_ir/src/relate/combine.rs
@@ -179,23 +179,9 @@ where
             Ok(a)
         }
 
-        (
-            ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)),
-            ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)),
-        ) => {
-            infcx.equate_effect_vids_raw(a_vid, b_vid);
-            Ok(a)
-        }
-
         // All other cases of inference with other variables are errors.
-        (
-            ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)),
-            ty::ConstKind::Infer(_),
-        )
-        | (
-            ty::ConstKind::Infer(_),
-            ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)),
-        ) => {
+        (ty::ConstKind::Infer(ty::InferConst::Var(_)), ty::ConstKind::Infer(_))
+        | (ty::ConstKind::Infer(_), ty::ConstKind::Infer(ty::InferConst::Var(_))) => {
             panic!(
                 "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}"
             )
@@ -211,16 +197,6 @@ where
             Ok(a)
         }
 
-        (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => {
-            infcx.instantiate_effect_var_raw(vid, b);
-            Ok(b)
-        }
-
-        (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => {
-            infcx.instantiate_effect_var_raw(vid, a);
-            Ok(a)
-        }
-
         (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
             if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() =>
         {
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 9e6fbc8ea0c..8db1258b65f 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -1393,7 +1393,6 @@ pub struct Generics {
     pub param_def_id_to_index: Vec<(GenericDef, u32)>,
     pub has_self: bool,
     pub has_late_bound_regions: Option<Span>,
-    pub host_effect_index: Option<usize>,
 }
 
 #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index aed6be4c627..1237fc82a17 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1069,47 +1069,3 @@ pub trait FnPtr: Copy + Clone {
 pub macro SmartPointer($item:item) {
     /* compiler built-in */
 }
-
-// Support traits and types for the desugaring of const traits and
-// `~const` bounds. Not supposed to be used by anything other than
-// the compiler.
-#[doc(hidden)]
-#[unstable(
-    feature = "effect_types",
-    issue = "none",
-    reason = "internal module for implementing effects"
-)]
-#[allow(missing_debug_implementations)] // these unit structs don't need `Debug` impls.
-pub mod effects {
-    #[lang = "EffectsNoRuntime"]
-    pub struct NoRuntime;
-    #[lang = "EffectsMaybe"]
-    pub struct Maybe;
-    #[lang = "EffectsRuntime"]
-    pub struct Runtime;
-
-    #[lang = "EffectsCompat"]
-    pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {}
-
-    impl Compat<false> for NoRuntime {}
-    impl Compat<true> for Runtime {}
-    impl<#[rustc_runtime] const RUNTIME: bool> Compat<RUNTIME> for Maybe {}
-
-    #[lang = "EffectsTyCompat"]
-    #[marker]
-    pub trait TyCompat<T: ?Sized> {}
-
-    impl<T: ?Sized> TyCompat<T> for T {}
-    impl<T: ?Sized> TyCompat<Maybe> for T {}
-
-    #[lang = "EffectsIntersection"]
-    pub trait Intersection {
-        #[lang = "EffectsIntersectionOutput"]
-        type Output: ?Sized;
-    }
-
-    // FIXME(effects): remove this after next trait solver lands
-    impl Intersection for () {
-        type Output = Maybe;
-    }
-}
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index d966f993104..31e4e79c00a 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -156,7 +156,7 @@ fn clean_param_env<'tcx>(
         .iter()
         .inspect(|param| {
             if cfg!(debug_assertions) {
-                debug_assert!(!param.is_anonymous_lifetime() && !param.is_host_effect());
+                debug_assert!(!param.is_anonymous_lifetime());
                 if let ty::GenericParamDefKind::Type { synthetic, .. } = param.kind {
                     debug_assert!(!synthetic && param.name != kw::SelfUpper);
                 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bf168809e28..81264b49dfd 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -368,7 +368,9 @@ pub(crate) fn clean_predicate<'tcx>(
         // FIXME(generic_const_exprs): should this do something?
         ty::ClauseKind::ConstEvaluatable(..)
         | ty::ClauseKind::WellFormed(..)
-        | ty::ClauseKind::ConstArgHasType(..) => None,
+        | ty::ClauseKind::ConstArgHasType(..)
+        // FIXME(effects): We can probably use this `HostEffect` pred to render `~const`.
+        | ty::ClauseKind::HostEffect(_) => None,
     }
 }
 
@@ -542,7 +544,7 @@ fn clean_generic_param_def(
                 synthetic,
             })
         }
-        ty::GenericParamDefKind::Const { has_default, synthetic, is_host_effect: _ } => {
+        ty::GenericParamDefKind::Const { has_default, synthetic } => {
             (def.name, GenericParamDefKind::Const {
                 ty: Box::new(clean_middle_ty(
                     ty::Binder::dummy(
@@ -617,7 +619,7 @@ fn clean_generic_param<'tcx>(
                 synthetic,
             })
         }
-        hir::GenericParamKind::Const { ty, default, synthetic, is_host_effect: _ } => {
+        hir::GenericParamKind::Const { ty, default, synthetic } => {
             (param.name.ident().name, GenericParamDefKind::Const {
                 ty: Box::new(clean_ty(ty, cx)),
                 default: default.map(|ct| {
@@ -797,7 +799,7 @@ fn clean_ty_generics<'tcx>(
                 }
                 true
             }
-            ty::GenericParamDefKind::Const { is_host_effect, .. } => !is_host_effect,
+            ty::GenericParamDefKind::Const { .. } => true,
         })
         .map(|param| clean_generic_param_def(param, ParamDefaults::Yes, cx))
         .collect();
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 6090de16d55..c8cb9267eb2 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1366,8 +1366,7 @@ impl GenericParamDef {
 
     pub(crate) fn is_synthetic_param(&self) -> bool {
         match self.kind {
-            GenericParamDefKind::Lifetime { .. } => false,
-            GenericParamDefKind::Const { synthetic: is_host_effect, .. } => is_host_effect,
+            GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false,
             GenericParamDefKind::Type { synthetic, .. } => synthetic,
         }
     }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index fdf628b50fb..d3a545fe0b6 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -114,10 +114,6 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
 
         // Elide internal host effect args.
         let param = generics.param_at(index, cx.tcx);
-        if param.is_host_effect() {
-            return None;
-        }
-
         let arg = ty::Binder::bind_with_vars(arg, bound_vars);
 
         // Elide arguments that coincide with their default.
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 91ec120adbf..3021f21df12 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -207,16 +207,7 @@ fn path_segment_certainty(
             if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
                 let generics = cx.tcx.generics_of(def_id);
 
-                let own_count = generics.own_params.len()
-                    - usize::from(generics.host_effect_index.is_some_and(|index| {
-                        // Check that the host index actually belongs to this resolution.
-                        // E.g. for `Add::add`, host_effect_index is `Some(2)`, but it's part of the parent `Add`
-                        // trait's generics.
-                        // Add params:      [Self#0, Rhs#1, host#2]   parent_count=0, count=3
-                        // Add::add params: []                        parent_count=3, count=3
-                        // (3..3).contains(&host_effect_index) => false
-                        (generics.parent_count..generics.count()).contains(&index)
-                    }));
+                let own_count = generics.own_params.len();
                 let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 {
                     Certainty::Certain(None)
                 } else {
@@ -310,8 +301,7 @@ fn type_is_inferable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> bo
 
     // Check that all type parameters appear in the functions input types.
     (0..(generics.parent_count + generics.own_params.len()) as u32).all(|index| {
-        Some(index as usize) == generics.host_effect_index
-            || fn_sig
+        fn_sig
                 .inputs()
                 .iter()
                 .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
diff --git a/tests/crashes/118320.rs b/tests/crashes/118320.rs
deleted file mode 100644
index 093c58e1c05..00000000000
--- a/tests/crashes/118320.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: #118320
-//@ edition:2021
-#![feature(const_trait_impl, effects, const_closures)]
-
-#[const_trait]
-trait Bar {
-    fn foo(&self);
-}
-
-impl Bar for () {}
-
-const FOO: () = {
-    (const || (()).foo())();
-};
diff --git a/tests/crashes/119924-6.rs b/tests/crashes/119924-6.rs
deleted file mode 100644
index f1cc9d29159..00000000000
--- a/tests/crashes/119924-6.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: #119924
-//@ compile-flags: -Znext-solver
-#![feature(const_trait_impl, effects)]
-
-struct S;
-#[const_trait]
-trait Trait<const N: u32> {}
-
-const fn f<T: Trait<{
-    struct I<U: ~const Trait<0>>(U); // should've gotten rejected during AST validation
-    //~^ ICE no host param id for call in const yet no errors reported
-    0
-}>>() {}
-
-pub fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr
index 98bb8196810..a0ca33e38ef 100644
--- a/tests/ui/const-generics/issues/issue-88119.stderr
+++ b/tests/ui/const-generics/issues/issue-88119.stderr
@@ -11,30 +11,12 @@ error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{con
    |
 LL | impl<T: ?Sized + ConstName> const ConstName for &T
    |                                                 ^^ cannot normalize `<&T as ConstName>::{constant#0}`
-   |
-note: required for `&T` to implement `ConstName`
-  --> $DIR/issue-88119.rs:19:35
-   |
-LL | impl<T: ?Sized + ConstName> const ConstName for &T
-   |                                   ^^^^^^^^^     ^^
-LL | where
-LL |     [(); name_len::<T>()]:,
-   |     --------------------- unsatisfied trait bound introduced here
 
 error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}`
   --> $DIR/issue-88119.rs:26:49
    |
 LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
    |                                                 ^^^^^^ cannot normalize `<&mut T as ConstName>::{constant#0}`
-   |
-note: required for `&mut T` to implement `ConstName`
-  --> $DIR/issue-88119.rs:26:35
-   |
-LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
-   |                                   ^^^^^^^^^     ^^^^^^
-LL | where
-LL |     [(); name_len::<T>()]:,
-   |     --------------------- unsatisfied trait bound introduced here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr
index 42a42ae3938..8cb91d78f6c 100644
--- a/tests/ui/consts/const-block-const-bound.stderr
+++ b/tests/ui/consts/const-block-const-bound.stderr
@@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn f<T: ~const Destruct>(x: T) {}
    |                      ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-block-const-bound.rs:8:22
+   |
+LL | const fn f<T: ~const Destruct>(x: T) {}
+   |                      ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
   --> $DIR/const-block-const-bound.rs:8:32
    |
@@ -12,6 +20,6 @@ LL | const fn f<T: ~const Destruct>(x: T) {}
    |                                |
    |                                the destructor for this type cannot be evaluated in constant functions
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs
index 9089dd70a26..2862b6ffb17 100644
--- a/tests/ui/consts/const-try.rs
+++ b/tests/ui/consts/const-try.rs
@@ -1,4 +1,4 @@
-//@ known-bug: #110395
+//@ compile-flags: -Znext-solver
 
 // Demonstrates what's needed to make use of `?` in const contexts.
 
@@ -14,12 +14,14 @@ struct TryMe;
 struct Error;
 
 impl const FromResidual<Error> for TryMe {
+    //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
     fn from_residual(residual: Error) -> Self {
         TryMe
     }
 }
 
 impl const Try for TryMe {
+    //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]`
     type Output = ();
     type Residual = Error;
     fn from_output(output: Self::Output) -> Self {
diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr
index 8afdd4e0d61..ba9da242107 100644
--- a/tests/ui/consts/const-try.stderr
+++ b/tests/ui/consts/const-try.stderr
@@ -1,8 +1,3 @@
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
 error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
   --> $DIR/const-try.rs:16:12
    |
@@ -13,7 +8,7 @@ LL | impl const FromResidual<Error> for TryMe {
    = 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:22:12
+  --> $DIR/const-try.rs:23:12
    |
 LL | impl const Try for TryMe {
    |            ^^^
@@ -21,5 +16,5 @@ LL | impl const Try for 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: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr
index 7de10f0287b..2195cab3f4d 100644
--- a/tests/ui/consts/constifconst-call-in-const-position.stderr
+++ b/tests/ui/consts/constifconst-call-in-const-position.stderr
@@ -3,24 +3,12 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
    = note: the next trait solver must be enabled globally for the effects feature to work correctly
    = help: use `-Znext-solver` to enable
 
-error[E0308]: mismatched types
+error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
   --> $DIR/constifconst-call-in-const-position.rs:17:38
    |
 LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
-   |                                      ^^^^^^ expected `false`, found `host`
-   |
-   = note: expected constant `false`
-              found constant `host`
-
-error[E0308]: mismatched types
-  --> $DIR/constifconst-call-in-const-position.rs:18:9
-   |
-LL |     [0; T::a()]
-   |         ^^^^^^ expected `false`, found `host`
-   |
-   = note: expected constant `false`
-              found constant `host`
+   |                                      ^^^^^^ calling non-const function `<() as Tr>::a`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr
index 218c90f89a9..2b012432afd 100644
--- a/tests/ui/consts/fn_trait_refs.stderr
+++ b/tests/ui/consts/fn_trait_refs.stderr
@@ -31,6 +31,22 @@ LL |     T: ~const Fn<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:13:15
+   |
+LL |     T: ~const Fn<()> + ~const Destruct,
+   |               ^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:13:31
+   |
+LL |     T: ~const Fn<()> + ~const Destruct,
+   |                               ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/fn_trait_refs.rs:20:15
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
@@ -51,10 +67,34 @@ LL |     T: ~const FnMut<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:20:15
+   |
+LL |     T: ~const FnMut<()> + ~const Destruct,
+   |               ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:20:34
+   |
+LL |     T: ~const FnMut<()> + ~const Destruct,
+   |                                  ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:27:15
+   |
+LL |     T: ~const FnOnce<()>,
+   |               ^^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/fn_trait_refs.rs:27:15
    |
 LL |     T: ~const FnOnce<()>,
    |               ^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/fn_trait_refs.rs:27:15
@@ -85,6 +125,22 @@ LL |     T: ~const Fn<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:34:15
+   |
+LL |     T: ~const Fn<()> + ~const Destruct,
+   |               ^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:34:31
+   |
+LL |     T: ~const Fn<()> + ~const Destruct,
+   |                               ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/fn_trait_refs.rs:48:15
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
@@ -104,6 +160,22 @@ LL |     T: ~const FnMut<()> + ~const Destruct,
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:48:15
+   |
+LL |     T: ~const FnMut<()> + ~const Destruct,
+   |               ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/fn_trait_refs.rs:48:34
+   |
+LL |     T: ~const FnMut<()> + ~const Destruct,
+   |                                  ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0015]: cannot call non-const operator in constants
   --> $DIR/fn_trait_refs.rs:70:17
    |
@@ -212,7 +284,7 @@ LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
 LL | }
    | - value is dropped here
 
-error: aborting due to 25 previous errors
+error: aborting due to 34 previous errors
 
 Some errors have detailed explanations: E0015, E0493, E0635.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr
index 6c83eff4de0..59476f98603 100644
--- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr
+++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr
@@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
    |                                       ^^^^^^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/unstable-const-fn-in-libcore.rs:19:39
+   |
+LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
+   |                                       ^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/unstable-const-fn-in-libcore.rs:24:26
    |
@@ -38,7 +46,7 @@ LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
 LL |     }
    |     - value is dropped here
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0015, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs
index ee2bf9e33eb..b2b3c61a722 100644
--- a/tests/ui/delegation/ice-issue-124347.rs
+++ b/tests/ui/delegation/ice-issue-124347.rs
@@ -4,7 +4,7 @@
 // FIXME(fn_delegation): `recursive delegation` error should be emitted here
 trait Trait {
     reuse Trait::foo { &self.0 }
-    //~^ ERROR cycle detected when computing generics of `Trait::foo`
+    //~^ ERROR recursive delegation is not supported yet
 }
 
 reuse foo;
diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr
index bd0bc970b94..74c4b5cd949 100644
--- a/tests/ui/delegation/ice-issue-124347.stderr
+++ b/tests/ui/delegation/ice-issue-124347.stderr
@@ -1,16 +1,8 @@
-error[E0391]: cycle detected when computing generics of `Trait::foo`
+error: recursive delegation is not supported yet
   --> $DIR/ice-issue-124347.rs:6:18
    |
 LL |     reuse Trait::foo { &self.0 }
-   |                  ^^^
-   |
-   = note: ...which immediately requires computing generics of `Trait::foo` again
-note: cycle used when inheriting delegation signature
-  --> $DIR/ice-issue-124347.rs:6:18
-   |
-LL |     reuse Trait::foo { &self.0 }
-   |                  ^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+   |                  ^^^ callee defined here
 
 error[E0391]: cycle detected when computing generics of `foo`
   --> $DIR/ice-issue-124347.rs:10:7
diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs
index e57effff48d..56296db85a3 100644
--- a/tests/ui/delegation/unsupported.rs
+++ b/tests/ui/delegation/unsupported.rs
@@ -51,7 +51,7 @@ mod effects {
     }
 
     reuse Trait::foo;
-    //~^ ERROR delegation to a function with effect parameter is not supported yet
+    //~^ ERROR type annotations needed
 }
 
 fn main() {}
diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr
index 6a627be3b64..1c79a603503 100644
--- a/tests/ui/delegation/unsupported.stderr
+++ b/tests/ui/delegation/unsupported.stderr
@@ -81,15 +81,15 @@ LL |         pub reuse to_reuse2::foo;
 LL |     reuse to_reuse1::foo;
    |                      ^^^
 
-error: delegation to a function with effect parameter is not supported yet
+error[E0283]: type annotations needed
   --> $DIR/unsupported.rs:53:18
    |
-LL |         fn foo();
-   |         --------- callee defined here
-...
 LL |     reuse Trait::foo;
-   |                  ^^^
+   |                  ^^^ cannot infer type
+   |
+   = note: cannot satisfy `_: effects::Trait`
 
 error: aborting due to 5 previous errors; 2 warnings emitted
 
-For more information about this error, try `rustc --explain E0391`.
+Some errors have detailed explanations: E0283, E0391.
+For more information about an error, try `rustc --explain E0283`.
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index e0d193b5d40..f1e6207ed81 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -10,6 +10,22 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
    |                                                                     ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/normalize-tait-in-const.rs:26:42
+   |
+LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
+   |                                          ^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/normalize-tait-in-const.rs:26:69
+   |
+LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
+   |                                                                     ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/normalize-tait-in-const.rs:27:5
    |
@@ -35,7 +51,7 @@ LL |     fun(filter_positive());
 LL | }
    | - value is dropped here
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0015, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr
index 643f1de3e8d..746b08fa710 100644
--- a/tests/ui/specialization/const_trait_impl.stderr
+++ b/tests/ui/specialization/const_trait_impl.stderr
@@ -1,23 +1,3 @@
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const_trait_impl.rs:6:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub unsafe trait Sup {
-LL |     fn foo() -> u32;
-   |           - expected 0 const parameters
-
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const_trait_impl.rs:6:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub unsafe trait Sup {
-LL |     fn foo() -> u32;
-   |           - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const_trait_impl.rs:34:16
    |
@@ -36,34 +16,27 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | impl<T: ~const Default + ~const Sub> const A for T {
    |                ^^^^^^^
 
-error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const_trait_impl.rs:29:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub trait A {
-LL |     fn a() -> u32;
-   |         - expected 0 const parameters
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const_trait_impl.rs:40:16
+   |
+LL | impl<T: ~const Default + ~const Sup> const A for T {
+   |                ^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const_trait_impl.rs:29:1
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const_trait_impl.rs:34:16
    |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub trait A {
-LL |     fn a() -> u32;
-   |         - expected 0 const parameters
+LL | impl<T: ~const Default> const A for T {
+   |                ^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const_trait_impl.rs:29:1
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const_trait_impl.rs:46:16
    |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub trait A {
-LL |     fn a() -> u32;
-   |         - expected 0 const parameters
+LL | impl<T: ~const Default + ~const Sub> const A for T {
+   |                ^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
@@ -115,7 +88,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 12 previous errors
+error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
index 4399ae2d1be..5a54e8eec91 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
@@ -1,3 +1,4 @@
+//@ compile-flags: -Znext-solver
 //@ known-bug: unknown
 
 #![allow(incomplete_features)]
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
index 8288c660ce7..35069a5a52f 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
@@ -1,46 +1,15 @@
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
-error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
-  --> $DIR/assoc-type-const-bound-usage-0.rs:13:5
+error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
+  --> $DIR/assoc-type-const-bound-usage-0.rs:14:5
    |
 LL |     T::Assoc::func()
-   |     ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
-   |
-note: required by a bound in `Trait::func`
-  --> $DIR/assoc-type-const-bound-usage-0.rs:6:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
-...
-LL |     fn func() -> i32;
-   |        ---- required by a bound in this associated function
-help: consider further restricting the associated type
-   |
-LL | const fn unqualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
-   |                                                ++++++++++++++++++++++++++++++++
+   |     ^^^^^^^^^^^^^^^^ types differ
 
-error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
-  --> $DIR/assoc-type-const-bound-usage-0.rs:17:5
+error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
+  --> $DIR/assoc-type-const-bound-usage-0.rs:18:5
    |
 LL |     <T as Trait>::Assoc::func()
-   |     ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
-   |
-note: required by a bound in `Trait::func`
-  --> $DIR/assoc-type-const-bound-usage-0.rs:6:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
-...
-LL |     fn func() -> i32;
-   |        ---- required by a bound in this associated function
-help: consider further restricting the associated type
-   |
-LL | const fn qualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
-   |                                              ++++++++++++++++++++++++++++++++
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs
index 8a1bf75f87e..04ad94556c3 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs
@@ -1,5 +1,5 @@
+//@ compile-flags: -Znext-solver
 //@ known-bug: unknown
-// FIXME(effects)
 
 #![feature(const_trait_impl, effects, generic_const_exprs)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
index 0792d090321..ed9182c7334 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
@@ -1,46 +1,23 @@
-error: using `#![feature(effects)]` without enabling next trait solver globally
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/assoc-type-const-bound-usage-1.rs:4:39
    |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
+LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
+   |                                       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
 
-error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
+error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
   --> $DIR/assoc-type-const-bound-usage-1.rs:15:44
    |
 LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
-   |                                            ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
-   |
-note: required by a bound in `Trait::func`
-  --> $DIR/assoc-type-const-bound-usage-1.rs:7:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
-...
-LL |     fn func() -> i32;
-   |        ---- required by a bound in this associated function
-help: consider further restricting the associated type
-   |
-LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> where <T as Trait>::Assoc: Trait {
-   |                                                                ++++++++++++++++++++++++++++++++
+   |                                            ^^^^^^^^^^^^^^^^ types differ
 
-error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
+error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
   --> $DIR/assoc-type-const-bound-usage-1.rs:19:42
    |
 LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> {
-   |                                          ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
-   |
-note: required by a bound in `Trait::func`
-  --> $DIR/assoc-type-const-bound-usage-1.rs:7:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
-...
-LL |     fn func() -> i32;
-   |        ---- required by a bound in this associated function
-help: consider further restricting the associated type
-   |
-LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> where <T as Trait>::Assoc: Trait {
-   |                                                                         ++++++++++++++++++++++++++++++++
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/const-traits/assoc-type.rs b/tests/ui/traits/const-traits/assoc-type.rs
index ea3cbabf302..a9394d90ed8 100644
--- a/tests/ui/traits/const-traits/assoc-type.rs
+++ b/tests/ui/traits/const-traits/assoc-type.rs
@@ -1,4 +1,5 @@
-// FIXME(effects): Replace `Add` with `std::ops::Add` once the latter a `#[const_trait]` again.
+//@ compile-flags: -Znext-solver
+
 #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
 
 #[const_trait]
@@ -33,7 +34,7 @@ trait Foo {
 
 impl const Foo for NonConstAdd {
     type Bar = NonConstAdd;
-    // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied
+    //~^ ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied
 }
 
 #[const_trait]
diff --git a/tests/ui/traits/const-traits/assoc-type.stderr b/tests/ui/traits/const-traits/assoc-type.stderr
index c20b53c210f..5c77754200a 100644
--- a/tests/ui/traits/const-traits/assoc-type.stderr
+++ b/tests/ui/traits/const-traits/assoc-type.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/assoc-type.rs:2:30
+  --> $DIR/assoc-type.rs:3:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^
@@ -7,10 +7,18 @@ LL | #![feature(const_trait_impl, effects)]
    = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
+error[E0277]: the trait bound `NonConstAdd: ~const Add` is not satisfied
+  --> $DIR/assoc-type.rs:36:16
    |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
+LL |     type Bar = NonConstAdd;
+   |                ^^^^^^^^^^^
+   |
+note: required by a bound in `Foo::Bar`
+  --> $DIR/assoc-type.rs:32:15
+   |
+LL |     type Bar: ~const Add;
+   |               ^^^^^^^^^^ required by this bound in `Foo::Bar`
 
 error: aborting due to 1 previous error; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/call-const-closure.rs b/tests/ui/traits/const-traits/call-const-closure.rs
new file mode 100644
index 00000000000..cbf3e6c3ac4
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-closure.rs
@@ -0,0 +1,22 @@
+//@ compile-flags: -Znext-solver
+//@ edition:2021
+
+#![feature(const_trait_impl, effects, const_closures)]
+#![allow(incomplete_features)]
+
+#[const_trait]
+trait Bar {
+    fn foo(&self);
+}
+
+impl Bar for () {
+    fn foo(&self) {}
+}
+
+const FOO: () = {
+    (const || ().foo())();
+    //~^ ERROR the trait bound `(): ~const Bar` is not satisfied
+    // FIXME(effects): The constness environment for const closures is wrong.
+};
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-const-closure.stderr b/tests/ui/traits/const-traits/call-const-closure.stderr
new file mode 100644
index 00000000000..3fed67f5d08
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-closure.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `(): ~const Bar` is not satisfied
+  --> $DIR/call-const-closure.rs:17:15
+   |
+LL |     (const || ().foo())();
+   |               ^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/call-const-in-tilde-const.rs b/tests/ui/traits/const-traits/call-const-in-tilde-const.rs
new file mode 100644
index 00000000000..970ee93fd49
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-in-tilde-const.rs
@@ -0,0 +1,14 @@
+//@ compile-flags: -Znext-solver
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Foo {
+    fn foo();
+}
+
+const fn foo<T: ~const Foo>() {
+    const { T::foo() }
+    //~^ ERROR the trait bound `T: const Foo` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-const-in-tilde-const.stderr b/tests/ui/traits/const-traits/call-const-in-tilde-const.stderr
new file mode 100644
index 00000000000..49c310f1f75
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-in-tilde-const.stderr
@@ -0,0 +1,18 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/call-const-in-tilde-const.rs:2:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `T: const Foo` is not satisfied
+  --> $DIR/call-const-in-tilde-const.rs:10:13
+   |
+LL |     const { T::foo() }
+   |             ^^^^^^^^
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr
index 5d2333d94fe..40a06af85ed 100644
--- a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr
+++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr
@@ -2,20 +2,7 @@ error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
   --> $DIR/call-const-trait-method-fail.rs:27:5
    |
 LL |     a.plus(b)
-   |     ^ the trait `Plus` is not implemented for `u32`
-   |
-note: required by a bound in `Plus::plus`
-  --> $DIR/call-const-trait-method-fail.rs:5:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Plus::plus`
-LL | pub trait Plus {
-LL |     fn plus(self, rhs: Self) -> Self;
-   |        ---- required by a bound in this associated function
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: Plus {
-   |                                             +++++++++++++++
+   |     ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
index bf455a714a3..c1cead54216 100644
--- a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
@@ -16,15 +16,6 @@ LL | impl const PartialEq 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
 
-error[E0049]: method `plus` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/call-const-trait-method-pass.rs:24:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub trait Plus {
-LL |     fn plus(self, rhs: Self) -> Self;
-   |            - expected 0 const parameters
-
 error[E0015]: cannot call non-const operator in constants
   --> $DIR/call-const-trait-method-pass.rs:39:22
    |
@@ -73,7 +64,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/call-generic-in-impl.stderr b/tests/ui/traits/const-traits/call-generic-in-impl.stderr
index 5cd274c6c5a..368c22675e7 100644
--- a/tests/ui/traits/const-traits/call-generic-in-impl.stderr
+++ b/tests/ui/traits/const-traits/call-generic-in-impl.stderr
@@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | impl<T: ~const PartialEq> const MyPartialEq for T {
    |                ^^^^^^^^^
 
-error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/call-generic-in-impl.rs:5:1
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-in-impl.rs:10:16
+   |
+LL | impl<T: ~const PartialEq> const MyPartialEq for T {
+   |                ^^^^^^^^^
    |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait MyPartialEq {
-LL |     fn eq(&self, other: &Self) -> bool;
-   |          - expected 0 const parameters
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0015]: cannot call non-const fn `<T as PartialEq>::eq` in constant functions
   --> $DIR/call-generic-in-impl.rs:12:9
@@ -27,5 +26,4 @@ LL + #![feature(effects)]
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.rs b/tests/ui/traits/const-traits/call-generic-method-chain.rs
index 9df694a02f5..e5baedae818 100644
--- a/tests/ui/traits/const-traits/call-generic-method-chain.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-chain.rs
@@ -1,6 +1,7 @@
 //! Basic test for calling methods on generic type parameters in `const fn`.
 
 //@ known-bug: #110395
+//@ compile-flags: -Znext-solver
 // FIXME(effects) check-pass
 
 #![feature(const_trait_impl, effects)]
diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.stderr b/tests/ui/traits/const-traits/call-generic-method-chain.stderr
index 57d57dfd5b9..62eed0f14f9 100644
--- a/tests/ui/traits/const-traits/call-generic-method-chain.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-chain.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/call-generic-method-chain.rs:6:30
+  --> $DIR/call-generic-method-chain.rs:7:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^
@@ -7,13 +7,8 @@ LL | #![feature(const_trait_impl, effects)]
    = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
 error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-chain.rs:10:12
+  --> $DIR/call-generic-method-chain.rs:11:12
    |
 LL | impl const PartialEq for S {
    |            ^^^^^^^^^
@@ -22,16 +17,32 @@ LL | impl const PartialEq for S {
    = 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:19:32
+  --> $DIR/call-generic-method-chain.rs:20:32
+   |
+LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
+   |                                ^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-chain.rs:20:32
    |
 LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
    |                                ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/call-generic-method-chain.rs:23:40
+  --> $DIR/call-generic-method-chain.rs:24:40
    |
 LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
    |                                        ^^^^^^^^^
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-chain.rs:24:40
+   |
+LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
+   |                                        ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors; 1 warning emitted
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs
index f46a34911f1..83a4bb25436 100644
--- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs
@@ -1,3 +1,4 @@
+//@ compile-flags: -Znext-solver
 //@ known-bug: #110395
 // FIXME(effects) check-pass
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr
index 0088ed2eb13..3f9dce919d0 100644
--- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/call-generic-method-dup-bound.rs:4:30
+  --> $DIR/call-generic-method-dup-bound.rs:5:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^
@@ -7,13 +7,8 @@ LL | #![feature(const_trait_impl, effects)]
    = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
 error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-dup-bound.rs:8:12
+  --> $DIR/call-generic-method-dup-bound.rs:9:12
    |
 LL | impl const PartialEq for S {
    |            ^^^^^^^^^
@@ -22,16 +17,32 @@ LL | impl const PartialEq for S {
    = 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:19:44
+  --> $DIR/call-generic-method-dup-bound.rs:20:44
+   |
+LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
+   |                                            ^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-dup-bound.rs:20:44
    |
 LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
    |                                            ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/call-generic-method-dup-bound.rs:26:37
+  --> $DIR/call-generic-method-dup-bound.rs:27:37
    |
 LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
    |                                     ^^^^^^^^^
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-dup-bound.rs:27:37
+   |
+LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
+   |                                     ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors; 1 warning emitted
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
index 68c9fc40010..06b99375cda 100644
--- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
@@ -1,20 +1,8 @@
 error[E0277]: the trait bound `S: const Foo` is not satisfied
-  --> $DIR/call-generic-method-nonconst.rs:25:34
+  --> $DIR/call-generic-method-nonconst.rs:25:22
    |
 LL | pub const EQ: bool = equals_self(&S);
-   |                      ----------- ^^ the trait `Foo` is not implemented for `S`
-   |                      |
-   |                      required by a bound introduced by this call
-   |
-note: required by a bound in `equals_self`
-  --> $DIR/call-generic-method-nonconst.rs:18:25
-   |
-LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
-   |                         ^^^^^^^^^^ required by this bound in `equals_self`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | pub const EQ: bool where S: Foo = equals_self(&S);
-   |                    ++++++++++++
+   |                      ^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.rs b/tests/ui/traits/const-traits/call-generic-method-pass.rs
index 413685d8b34..cbeeb2567dd 100644
--- a/tests/ui/traits/const-traits/call-generic-method-pass.rs
+++ b/tests/ui/traits/const-traits/call-generic-method-pass.rs
@@ -1,5 +1,6 @@
 //! Basic test for calling methods on generic type parameters in `const fn`.
 
+//@ compile-flags: -Znext-solver
 //@ known-bug: #110395
 // FIXME(effects) check-pass
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.stderr b/tests/ui/traits/const-traits/call-generic-method-pass.stderr
index 4a6100c3c1a..e35de48ed60 100644
--- a/tests/ui/traits/const-traits/call-generic-method-pass.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-pass.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/call-generic-method-pass.rs:6:30
+  --> $DIR/call-generic-method-pass.rs:7:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^
@@ -7,13 +7,8 @@ LL | #![feature(const_trait_impl, effects)]
    = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
 error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-pass.rs:10:12
+  --> $DIR/call-generic-method-pass.rs:11:12
    |
 LL | impl const PartialEq for S {
    |            ^^^^^^^^^
@@ -22,10 +17,18 @@ LL | impl const PartialEq for S {
    = 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:19:32
+  --> $DIR/call-generic-method-pass.rs:20:32
+   |
+LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
+   |                                ^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-pass.rs:20:32
    |
 LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
    |                                ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 3 previous errors; 1 warning emitted
 
diff --git a/tests/ui/traits/const-traits/const-bound-in-host.rs b/tests/ui/traits/const-traits/const-bound-in-host.rs
new file mode 100644
index 00000000000..6fbc21074b6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-bound-in-host.rs
@@ -0,0 +1,15 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Foo {
+    fn foo();
+}
+
+fn foo<T: const Foo>() {
+    const { T::foo() }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-bound-in-host.stderr b/tests/ui/traits/const-traits/const-bound-in-host.stderr
new file mode 100644
index 00000000000..b815f745ee8
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-bound-in-host.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/const-bound-in-host.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs
index 099cf0b00d3..7c3e2af1797 100644
--- a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs
+++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Znext-solver
+
 #![allow(incomplete_features)]
 #![feature(const_trait_impl, effects)]
 
diff --git a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr
index b5d9b1fff8a..ae1260ffab7 100644
--- a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr
+++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr
@@ -1,31 +1,26 @@
 error: `~const` is not allowed here
-  --> $DIR/const-bound-on-not-const-associated-fn.rs:10:40
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:12:40
    |
 LL |     fn do_something_else() where Self: ~const MyTrait;
    |                                        ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
-  --> $DIR/const-bound-on-not-const-associated-fn.rs:10:8
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:12:8
    |
 LL |     fn do_something_else() where Self: ~const MyTrait;
    |        ^^^^^^^^^^^^^^^^^
 
 error: `~const` is not allowed here
-  --> $DIR/const-bound-on-not-const-associated-fn.rs:21:32
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:23:32
    |
 LL |     pub fn foo(&self) where T: ~const MyTrait {
    |                                ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
-  --> $DIR/const-bound-on-not-const-associated-fn.rs:21:12
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:23:12
    |
 LL |     pub fn foo(&self) where T: ~const MyTrait {
    |            ^^^
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs
index db446f8bc2e..d51d231b8a9 100644
--- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs
+++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs
@@ -5,6 +5,7 @@ trait NonConst {}
 
 const fn perform<T: ~const NonConst>() {}
 //~^ ERROR `~const` can only be applied to `#[const_trait]` traits
+//~| ERROR `~const` can only be applied to `#[const_trait]` traits
 
 fn operate<T: const NonConst>() {}
 //~^ ERROR `const` can only be applied to `#[const_trait]` traits
diff --git a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr
index e1a85fc5414..6c3c11c6a47 100644
--- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr
+++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr
@@ -18,11 +18,19 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn perform<T: ~const NonConst>() {}
    |                            ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-bounds-non-const-trait.rs:6:28
+   |
+LL | const fn perform<T: ~const NonConst>() {}
+   |                            ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error: `const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-bounds-non-const-trait.rs:9:21
+  --> $DIR/const-bounds-non-const-trait.rs:10:21
    |
 LL | fn operate<T: const NonConst>() {}
    |                     ^^^^^^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors; 1 warning emitted
 
diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs
index a1710e65252..7f9b38b8207 100644
--- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs
+++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Znext-solver
+
 #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
 
 struct S;
diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr
index 49cd1725c8c..ba12854987e 100644
--- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr
+++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/const-check-fns-in-const-impl.rs:1:30
+  --> $DIR/const-check-fns-in-const-impl.rs:3:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^
@@ -7,19 +7,14 @@ LL | #![feature(const_trait_impl, effects)]
    = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
 error[E0015]: cannot call non-const fn `non_const` in constant functions
-  --> $DIR/const-check-fns-in-const-impl.rs:12:16
+  --> $DIR/const-check-fns-in-const-impl.rs:14:16
    |
 LL |     fn foo() { non_const() }
    |                ^^^^^^^^^^^
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
index 507ceaae2ea..4e6707bba51 100644
--- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
+++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
@@ -1,17 +1,16 @@
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-closure-trait-method-fail.rs:5:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Tr {
-LL |     fn a(self) -> i32;
-   |         - expected 0 const parameters
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closure-trait-method-fail.rs:14:39
+   |
+LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
+   |                                       ^^^^^^^^^^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-closure-trait-method-fail.rs:14:39
    |
 LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
    |                                       ^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/const-closure-trait-method-fail.rs:15:5
@@ -31,5 +30,4 @@ LL + #![feature(effects)]
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
index 2a54cd5d7f6..0f0cd73cc10 100644
--- a/tests/ui/traits/const-traits/const-closure-trait-method.stderr
+++ b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
@@ -1,17 +1,16 @@
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-closure-trait-method.rs:5:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Tr {
-LL |     fn a(self) -> i32;
-   |         - expected 0 const parameters
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closure-trait-method.rs:14:39
+   |
+LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
+   |                                       ^^^^^^^^^^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-closure-trait-method.rs:14:39
    |
 LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
    |                                       ^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/const-closure-trait-method.rs:15:5
@@ -31,5 +30,4 @@ LL + #![feature(effects)]
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-closures.stderr b/tests/ui/traits/const-traits/const-closures.stderr
index a0f05325389..4d354cb281f 100644
--- a/tests/ui/traits/const-traits/const-closures.stderr
+++ b/tests/ui/traits/const-traits/const-closures.stderr
@@ -17,11 +17,43 @@ LL |         F: ~const Fn() -> u8,
    |                   ^^^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:8:19
+   |
+LL |         F: ~const FnOnce() -> u8,
+   |                   ^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:9:19
+   |
+LL |         F: ~const FnMut() -> u8,
+   |                   ^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:10:19
+   |
+LL |         F: ~const Fn() -> u8,
+   |                   ^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-closures.rs:23:27
    |
 LL | const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
    |                           ^^^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:23:27
+   |
+LL | const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
+   |                           ^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/const-closures.rs:24:5
    |
@@ -70,6 +102,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 7 previous errors
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr
index 0809d9c1e1d..071eaf49541 100644
--- a/tests/ui/traits/const-traits/const-default-method-bodies.stderr
+++ b/tests/ui/traits/const-traits/const-default-method-bodies.stderr
@@ -1,21 +1,8 @@
 error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
-  --> $DIR/const-default-method-bodies.rs:26:18
+  --> $DIR/const-default-method-bodies.rs:26:5
    |
 LL |     NonConstImpl.a();
-   |                  ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl`
-   |
-note: required by a bound in `ConstDefaultFn::a`
-  --> $DIR/const-default-method-bodies.rs:5:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a`
-...
-LL |     fn a(self) {
-   |        - required by a bound in this associated function
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | const fn test() where NonConstImpl: ConstDefaultFn {
-   |                 ++++++++++++++++++++++++++++++++++
+   |     ^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr
index be197006f02..d94b0542324 100644
--- a/tests/ui/traits/const-traits/const-drop-bound.stderr
+++ b/tests/ui/traits/const-traits/const-drop-bound.stderr
@@ -5,6 +5,14 @@ LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct
    |                                                                    ^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-bound.rs:9:68
+   |
+LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
+   |                                                                    ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-drop-bound.rs:20:15
    |
 LL |     T: ~const Destruct,
@@ -16,12 +24,28 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL |     E: ~const Destruct,
    |               ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-bound.rs:20:15
+   |
+LL |     T: ~const Destruct,
+   |               ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-bound.rs:21:15
+   |
+LL |     E: ~const Destruct,
+   |               ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0493]: destructor of `E` cannot be evaluated at compile-time
   --> $DIR/const-drop-bound.rs:12:13
    |
 LL |         Err(_e) => None,
    |             ^^ the destructor for this type cannot be evaluated in constant functions
 
-error: aborting due to 4 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
index faf24c6d911..27e8053c969 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
@@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                          ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail-2.rs:20:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
   --> $DIR/const-drop-fail-2.rs:20:36
    |
@@ -33,7 +41,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0015, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
index 3d400bf0158..bde13b4d6cf 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
@@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                          ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail.rs:23:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
   --> $DIR/const-drop-fail.rs:23:36
    |
@@ -71,7 +79,7 @@ LL | | }
    | |_- in this macro invocation
    = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0080, E0493.
 For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
index fd0f6d02684..064ffacca42 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
@@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                          ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail.rs:23:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
   --> $DIR/const-drop-fail.rs:23:36
    |
@@ -21,6 +29,6 @@ LL | const fn check<T: ~const Destruct>(_: T) {}
    |                                    |
    |                                    the destructor for this type cannot be evaluated in constant functions
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr
index dd3ea5d241d..7b6d185c7cc 100644
--- a/tests/ui/traits/const-traits/const-drop.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop.precise.stderr
@@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn a<T: ~const Destruct>(_: T) {}
    |                      ^^^^^^^^
 
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-drop.rs:53:5
-   |
-LL |     #[const_trait]
-   |     ^^^^^^^^^^^^^^ found 1 const parameter
-LL |     pub trait SomeTrait {
-LL |         fn foo();
-   |               - expected 0 const parameters
-
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-drop.rs:53:5
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop.rs:18:22
    |
-LL |     #[const_trait]
-   |     ^^^^^^^^^^^^^^ found 1 const parameter
-LL |     pub trait SomeTrait {
-LL |         fn foo();
-   |               - expected 0 const parameters
+LL | const fn a<T: ~const Destruct>(_: T) {}
+   |                      ^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
@@ -78,7 +66,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0015, E0049, E0493.
+Some errors have detailed explanations: E0015, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr
index aa59e1c8dc4..b497c39b08a 100644
--- a/tests/ui/traits/const-traits/const-drop.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop.stock.stderr
@@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn a<T: ~const Destruct>(_: T) {}
    |                      ^^^^^^^^
 
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-drop.rs:53:5
-   |
-LL |     #[const_trait]
-   |     ^^^^^^^^^^^^^^ found 1 const parameter
-LL |     pub trait SomeTrait {
-LL |         fn foo();
-   |               - expected 0 const parameters
-
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-drop.rs:53:5
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop.rs:18:22
    |
-LL |     #[const_trait]
-   |     ^^^^^^^^^^^^^^ found 1 const parameter
-LL |     pub trait SomeTrait {
-LL |         fn foo();
-   |               - expected 0 const parameters
+LL | const fn a<T: ~const Destruct>(_: T) {}
+   |                      ^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
@@ -80,7 +68,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0015, E0049, E0493.
+Some errors have detailed explanations: E0015, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs
index b87387f4d5d..6d08d8bdd91 100644
--- a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs
+++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs
@@ -1,4 +1,6 @@
 //@ known-bug: #110395
+//@ failure-status: 101
+//@ dont-check-compiler-stderr
 // FIXME(effects) check-pass
 //@ compile-flags: -Znext-solver
 
@@ -86,51 +88,3 @@ trait Tuple {}
 trait LegacyReceiver {}
 
 impl<T: ?Sized> LegacyReceiver for &T {}
-
-impl<T: ?Sized> LegacyReceiver for &mut T {}
-
-#[stable(feature = "minicore", since = "1.0.0")]
-pub mod effects {
-    use super::Sized;
-
-    #[lang = "EffectsNoRuntime"]
-    #[stable(feature = "minicore", since = "1.0.0")]
-    pub struct NoRuntime;
-    #[lang = "EffectsMaybe"]
-    #[stable(feature = "minicore", since = "1.0.0")]
-    pub struct Maybe;
-    #[lang = "EffectsRuntime"]
-    #[stable(feature = "minicore", since = "1.0.0")]
-    pub struct Runtime;
-
-    #[lang = "EffectsCompat"]
-    #[stable(feature = "minicore", since = "1.0.0")]
-    pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {}
-
-    #[stable(feature = "minicore", since = "1.0.0")]
-    impl Compat<false> for NoRuntime {}
-    #[stable(feature = "minicore", since = "1.0.0")]
-    impl Compat<true> for Runtime {}
-    #[stable(feature = "minicore", since = "1.0.0")]
-    impl<#[rustc_runtime] const RUNTIME: bool> Compat<RUNTIME> for Maybe {}
-
-    #[lang = "EffectsTyCompat"]
-    #[marker]
-    #[stable(feature = "minicore", since = "1.0.0")]
-    pub trait TyCompat<T: ?Sized> {}
-
-    #[stable(feature = "minicore", since = "1.0.0")]
-    impl<T: ?Sized> TyCompat<T> for T {}
-    #[stable(feature = "minicore", since = "1.0.0")]
-    impl<T: ?Sized> TyCompat<T> for Maybe {}
-    #[stable(feature = "minicore", since = "1.0.0")]
-    impl<T: ?Sized> TyCompat<Maybe> for T {}
-
-    #[lang = "EffectsIntersection"]
-    #[stable(feature = "minicore", since = "1.0.0")]
-    pub trait Intersection {
-        #[lang = "EffectsIntersectionOutput"]
-        #[stable(feature = "minicore", since = "1.0.0")]
-        type Output: ?Sized;
-    }
-}
diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr b/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr
deleted file mode 100644
index 9eda9d98ec5..00000000000
--- a/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0277]: the trait bound `fn() {foo}: const FnOnce()` is not satisfied
-  --> $DIR/const-fns-are-early-bound.rs:31:17
-   |
-LL |     is_const_fn(foo);
-   |     ----------- ^^^ the trait `FnOnce()` is not implemented for fn item `fn() {foo}`
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `is_const_fn`
-  --> $DIR/const-fns-are-early-bound.rs:25:12
-   |
-LL |     fn is_const_fn<F>(_: F)
-   |        ----------- required by a bound in this function
-LL |     where
-LL |         F: const FnOnce<()>,
-   |            ^^^^^^^^^^^^^^^^ required by this bound in `is_const_fn`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs
index bd6f476f879..e49e9090eb4 100644
--- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs
+++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs
@@ -1,11 +1,10 @@
-//@ known-bug: #110395
-
+//@ compile-flags: -Znext-solver
 #![feature(const_trait_impl, effects)]
+#![allow(incomplete_features)]
 
 pub trait A {}
-// FIXME ~^ HELP: mark `A` as const
 
 impl const A for () {}
-// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
+//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr
index 2a030369093..828e2174f00 100644
--- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr
+++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr
@@ -1,28 +1,14 @@
-warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/const-impl-requires-const-trait.rs:3:30
-   |
-LL | #![feature(const_trait_impl, effects)]
-   |                              ^^^^^^^
-   |
-   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
-   = note: `#[warn(incomplete_features)]` on by default
-
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
 error: const `impl` for trait `A` which is not marked with `#[const_trait]`
-  --> $DIR/const-impl-requires-const-trait.rs:8:12
+  --> $DIR/const-impl-requires-const-trait.rs:7:12
    |
 LL | pub trait A {}
    | - help: mark `A` as const: `#[const_trait]`
-...
+LL |
 LL | impl const A for () {}
    |            ^
    |
    = 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 2 previous errors; 1 warning emitted
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs
index 51dfe29b829..61b8c9a5bff 100644
--- a/tests/ui/traits/const-traits/const-impl-trait.rs
+++ b/tests/ui/traits/const-traits/const-impl-trait.rs
@@ -1,4 +1,7 @@
+//@ compile-flags: -Znext-solver
 //@ known-bug: #110395
+//@ failure-status: 101
+//@ dont-check-compiler-stderr
 // Broken until we have `&T: const Deref` impl in stdlib
 
 #![allow(incomplete_features)]
diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr
deleted file mode 100644
index 1040af7541c..00000000000
--- a/tests/ui/traits/const-traits/const-impl-trait.stderr
+++ /dev/null
@@ -1,249 +0,0 @@
-error[E0635]: unknown feature `const_cmp`
-  --> $DIR/const-impl-trait.rs:8:5
-   |
-LL |     const_cmp,
-   |     ^^^^^^^^^
-
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:13:30
-   |
-LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
-   |                              ^^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:17:30
-   |
-LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct)
-   |                              ^^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:17:49
-   |
-LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct)
-   |                                                 ^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:18:20
-   |
-LL |     -> impl ~const PartialEq + ~const Destruct
-   |                    ^^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:18:39
-   |
-LL |     -> impl ~const PartialEq + ~const Destruct
-   |                                       ^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:18:20
-   |
-LL |     -> impl ~const PartialEq + ~const Destruct
-   |                    ^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:18:39
-   |
-LL |     -> impl ~const PartialEq + ~const Destruct
-   |                                       ^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:29
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                             ^^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:48
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                                                ^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:29
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                             ^^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:48
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                                                ^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:29
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                             ^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:29:48
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                                                ^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:50:41
-   |
-LL | const fn apit(_: impl ~const T + ~const Destruct) {}
-   |                                         ^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:54:73
-   |
-LL | const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
-   |                                                                         ^^^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:29
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                             ^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:48
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                                                ^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:29
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                             ^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:48
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                                                ^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:29
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                             ^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:25:48
-   |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
-   |                                                ^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:37:26
-   |
-LL |     assert!(wrap(123) == wrap(123));
-   |                          ^^^^^^^^^- value is dropped here
-   |                          |
-   |                          the destructor for this type cannot be evaluated in constants
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:37:26
-   |
-LL |     assert!(wrap(123) == wrap(123));
-   |                          ^^^^^^^^^- value is dropped here
-   |                          |
-   |                          the destructor for this type cannot be evaluated in constants
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:37:13
-   |
-LL |     assert!(wrap(123) == wrap(123));
-   |             ^^^^^^^^^             - value is dropped here
-   |             |
-   |             the destructor for this type cannot be evaluated in constants
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:37:13
-   |
-LL |     assert!(wrap(123) == wrap(123));
-   |             ^^^^^^^^^             - value is dropped here
-   |             |
-   |             the destructor for this type cannot be evaluated in constants
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:38:26
-   |
-LL |     assert!(wrap(123) != wrap(456));
-   |                          ^^^^^^^^^- value is dropped here
-   |                          |
-   |                          the destructor for this type cannot be evaluated in constants
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:38:26
-   |
-LL |     assert!(wrap(123) != wrap(456));
-   |                          ^^^^^^^^^- value is dropped here
-   |                          |
-   |                          the destructor for this type cannot be evaluated in constants
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:38:13
-   |
-LL |     assert!(wrap(123) != wrap(456));
-   |             ^^^^^^^^^             - value is dropped here
-   |             |
-   |             the destructor for this type cannot be evaluated in constants
-
-error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:38:13
-   |
-LL |     assert!(wrap(123) != wrap(456));
-   |             ^^^^^^^^^             - value is dropped here
-   |             |
-   |             the destructor for this type cannot be evaluated in constants
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `impl ~const T + ~const Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:50:15
-   |
-LL | const fn apit(_: impl ~const T + ~const Destruct) {}
-   |               ^                                    - value is dropped here
-   |               |
-   |               the destructor for this type cannot be evaluated in constant functions
-
-error[E0493]: destructor of `impl IntoIterator<Item : ~const T> + ~const Destruct` cannot be evaluated at compile-time
-  --> $DIR/const-impl-trait.rs:54:27
-   |
-LL | const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
-   |                           ^                                                        - value is dropped here
-   |                           |
-   |                           the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 33 previous errors
-
-Some errors have detailed explanations: E0493, E0635.
-For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/const-in-closure.rs b/tests/ui/traits/const-traits/const-in-closure.rs
new file mode 100644
index 00000000000..51b22c53036
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-in-closure.rs
@@ -0,0 +1,25 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Trait {
+    fn method();
+}
+
+const fn foo<T: Trait>() {
+    let _ = || {
+        // Make sure this doesn't enforce `T: ~const Trait`
+        T::method();
+    };
+}
+
+fn bar<T: const Trait>() {
+    let _ = || {
+        // Make sure unconditionally const bounds propagate from parent.
+        const { T::method(); };
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-in-closure.stderr b/tests/ui/traits/const-traits/const-in-closure.stderr
new file mode 100644
index 00000000000..f4b03b9ed20
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-in-closure.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/const-in-closure.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
index a34bae843c8..b6f2434140d 100644
--- a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
@@ -1,21 +1,8 @@
 error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
-  --> $DIR/cross-crate.rs:19:14
+  --> $DIR/cross-crate.rs:19:5
    |
 LL |     NonConst.func();
-   |              ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
-   |
-note: required by a bound in `func`
-  --> $DIR/auxiliary/cross-crate.rs:5:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func`
-...
-LL |     fn func(self);
-   |        ---- required by a bound in this associated function
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | const fn const_context() where cross_crate::NonConst: cross_crate::MyTrait {
-   |                          +++++++++++++++++++++++++++++++++++++++++++++++++
+   |     ^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr
index d0f22c0b9b6..7b4d512e391 100644
--- a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr
@@ -1,21 +1,8 @@
 error[E0277]: the trait bound `(): ~const Tr` is not satisfied
-  --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
+  --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:9
    |
 LL |         ().a()
-   |            ^ the trait `Tr` is not implemented for `()`
-   |
-note: required by a bound in `Tr::a`
-  --> $DIR/default-method-body-is-const-same-trait-ck.rs:5:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Tr::a`
-LL | pub trait Tr {
-LL |     fn a(&self) {}
-   |        - required by a bound in this associated function
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | pub trait Tr where (): Tr {
-   |              ++++++++++++
+   |         ^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/dont-observe-host-opaque.rs b/tests/ui/traits/const-traits/dont-observe-host-opaque.rs
new file mode 100644
index 00000000000..4a5ae346e39
--- /dev/null
+++ b/tests/ui/traits/const-traits/dont-observe-host-opaque.rs
@@ -0,0 +1,12 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+const fn opaque() -> impl Sized {}
+
+fn main() {
+    let mut x = const { opaque() };
+    x = opaque();
+}
diff --git a/tests/ui/traits/const-traits/dont-observe-host-opaque.stderr b/tests/ui/traits/const-traits/dont-observe-host-opaque.stderr
new file mode 100644
index 00000000000..1b457ab7643
--- /dev/null
+++ b/tests/ui/traits/const-traits/dont-observe-host-opaque.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/dont-observe-host-opaque.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/dont-observe-host.rs b/tests/ui/traits/const-traits/dont-observe-host.rs
new file mode 100644
index 00000000000..d027d578c42
--- /dev/null
+++ b/tests/ui/traits/const-traits/dont-observe-host.rs
@@ -0,0 +1,23 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait]
+trait Trait {
+    fn method() {}
+}
+
+impl const Trait for () {}
+
+fn main() {
+    let mut x = const {
+        let x = <()>::method;
+        x();
+        x
+    };
+    let y = <()>::method;
+    y();
+    x = y;
+}
diff --git a/tests/ui/traits/const-traits/dont-observe-host.stderr b/tests/ui/traits/const-traits/dont-observe-host.stderr
new file mode 100644
index 00000000000..64ef611f011
--- /dev/null
+++ b/tests/ui/traits/const-traits/dont-observe-host.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/dont-observe-host.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/effects/minicore.rs b/tests/ui/traits/const-traits/effects/minicore.rs
index 9b615450c68..a756f4d9f6c 100644
--- a/tests/ui/traits/const-traits/effects/minicore.rs
+++ b/tests/ui/traits/const-traits/effects/minicore.rs
@@ -536,35 +536,3 @@ fn test_const_eval_select() {
 
     const_eval_select((), const_fn, rt_fn);
 }
-
-mod effects {
-    use super::Sized;
-
-    #[lang = "EffectsNoRuntime"]
-    pub struct NoRuntime;
-    #[lang = "EffectsMaybe"]
-    pub struct Maybe;
-    #[lang = "EffectsRuntime"]
-    pub struct Runtime;
-
-    #[lang = "EffectsCompat"]
-    pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {}
-
-    impl Compat<false> for NoRuntime {}
-    impl Compat<true> for Runtime {}
-    impl<#[rustc_runtime] const RUNTIME: bool> Compat<RUNTIME> for Maybe {}
-
-    #[lang = "EffectsTyCompat"]
-    #[marker]
-    pub trait TyCompat<T: ?Sized> {}
-
-    impl<T: ?Sized> TyCompat<T> for T {}
-    impl<T: ?Sized> TyCompat<T> for Maybe {}
-    impl<T: ?Sized> TyCompat<Maybe> for T {}
-
-    #[lang = "EffectsIntersection"]
-    pub trait Intersection {
-        #[lang = "EffectsIntersectionOutput"]
-        type Output: ?Sized;
-    }
-}
diff --git a/tests/ui/traits/const-traits/effects/minicore.stderr b/tests/ui/traits/const-traits/effects/minicore.stderr
index 823ab69df9c..568d98cfe87 100644
--- a/tests/ui/traits/const-traits/effects/minicore.stderr
+++ b/tests/ui/traits/const-traits/effects/minicore.stderr
@@ -1,13 +1,13 @@
 error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
-#0 [check_well_formed] checking that `<impl at $DIR/minicore.rs:459:1: 459:36>` is well-formed
-#1 [check_mod_type_wf] checking that types are well-formed in top-level module
+#0 [typeck] type-checking `Clone::clone_from`
+#1 [analysis] running analysis passes on this crate
 end of query stack
 
 error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
-#0 [check_well_formed] checking that `drop` is well-formed
-#1 [check_mod_type_wf] checking that types are well-formed in top-level module
+#0 [typeck] type-checking `test_const_eval_select`
+#1 [analysis] running analysis passes on this crate
 end of query stack
diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr
index 8c591edac54..eea6a06c1c8 100644
--- a/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr
@@ -16,17 +16,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
   --> $DIR/no-explicit-const-params-cross-crate.rs:16:12
    |
 LL |     <() as Bar<false>>::bar();
-   |            ^^^ expected 0 generic arguments
+   |            ^^^------- help: remove the unnecessary generics
+   |            |
+   |            expected 0 generic arguments
    |
 note: trait defined here, with 0 generic parameters
   --> $DIR/auxiliary/cross-crate.rs:8:11
    |
 LL | pub trait Bar {
    |           ^^^
-help: replace the generic bound with the associated type
-   |
-LL |     <() as Bar< = false>>::bar();
-   |                 +
 
 error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/no-explicit-const-params-cross-crate.rs:7:5
@@ -46,17 +44,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
   --> $DIR/no-explicit-const-params-cross-crate.rs:9:12
    |
 LL |     <() as Bar<true>>::bar();
-   |            ^^^ expected 0 generic arguments
+   |            ^^^------ help: remove the unnecessary generics
+   |            |
+   |            expected 0 generic arguments
    |
 note: trait defined here, with 0 generic parameters
   --> $DIR/auxiliary/cross-crate.rs:8:11
    |
 LL | pub trait Bar {
    |           ^^^
-help: replace the generic bound with the associated type
-   |
-LL |     <() as Bar< = true>>::bar();
-   |                 +
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs
index 84f5f2803e1..b08aba9acbc 100644
--- a/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs
@@ -23,5 +23,4 @@ const FOO: () = {
     //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
     <() as Bar<false>>::bar();
     //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
-    //~| ERROR: mismatched types
 };
diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr
index cc08114ddb5..a3aa970e94d 100644
--- a/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr
@@ -30,26 +30,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
   --> $DIR/no-explicit-const-params.rs:24:12
    |
 LL |     <() as Bar<false>>::bar();
-   |            ^^^ expected 0 generic arguments
+   |            ^^^------- help: remove the unnecessary generics
+   |            |
+   |            expected 0 generic arguments
    |
 note: trait defined here, with 0 generic parameters
   --> $DIR/no-explicit-const-params.rs:6:7
    |
 LL | trait Bar {
    |       ^^^
-help: replace the generic bound with the associated type
-   |
-LL |     <() as Bar< = false>>::bar();
-   |                 +
-
-error[E0308]: mismatched types
-  --> $DIR/no-explicit-const-params.rs:24:5
-   |
-LL |     <() as Bar<false>>::bar();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `false`, found `true`
-   |
-   = note: expected constant `false`
-              found constant `true`
 
 error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/no-explicit-const-params.rs:15:5
@@ -69,19 +58,16 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
   --> $DIR/no-explicit-const-params.rs:17:12
    |
 LL |     <() as Bar<true>>::bar();
-   |            ^^^ expected 0 generic arguments
+   |            ^^^------ help: remove the unnecessary generics
+   |            |
+   |            expected 0 generic arguments
    |
 note: trait defined here, with 0 generic parameters
   --> $DIR/no-explicit-const-params.rs:6:7
    |
 LL | trait Bar {
    |       ^^^
-help: replace the generic bound with the associated type
-   |
-LL |     <() as Bar< = true>>::bar();
-   |                 +
 
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0107, E0308.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
index 0508b1c5e26..d29cd93d3fb 100644
--- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
+++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
@@ -1,4 +1,3 @@
-//@ check-fail
 // Fixes #119830
 
 #![feature(effects)] //~ WARN the feature `effects` is incomplete
diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
index e97a9615ae1..d9655c4995f 100644
--- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
+++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/spec-effectvar-ice.rs:4:12
+  --> $DIR/spec-effectvar-ice.rs:3:12
    |
 LL | #![feature(effects)]
    |            ^^^^^^^
@@ -13,7 +13,7 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
    = help: use `-Znext-solver` to enable
 
 error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
-  --> $DIR/spec-effectvar-ice.rs:12:15
+  --> $DIR/spec-effectvar-ice.rs:11:15
    |
 LL | trait Foo {}
    | - help: mark `Foo` as const: `#[const_trait]`
@@ -25,7 +25,7 @@ LL | impl<T> const Foo for T {}
    = note: adding a non-const method body in the future would be a breaking change
 
 error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
-  --> $DIR/spec-effectvar-ice.rs:15:15
+  --> $DIR/spec-effectvar-ice.rs:14:15
    |
 LL | trait Foo {}
    | - help: mark `Foo` as const: `#[const_trait]`
@@ -37,25 +37,25 @@ LL | impl<T> const Foo for T where T: const Specialize {}
    = 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/spec-effectvar-ice.rs:15:40
+  --> $DIR/spec-effectvar-ice.rs:14:40
    |
 LL | impl<T> const Foo for T where T: const Specialize {}
    |                                        ^^^^^^^^^^
 
 error: specialization impl does not specialize any associated items
-  --> $DIR/spec-effectvar-ice.rs:15:1
+  --> $DIR/spec-effectvar-ice.rs:14:1
    |
 LL | impl<T> const Foo for T where T: const Specialize {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: impl is a specialization of this impl
-  --> $DIR/spec-effectvar-ice.rs:12:1
+  --> $DIR/spec-effectvar-ice.rs:11:1
    |
 LL | impl<T> const Foo for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cannot specialize on trait `Specialize`
-  --> $DIR/spec-effectvar-ice.rs:15:34
+  --> $DIR/spec-effectvar-ice.rs:14:34
    |
 LL | impl<T> const Foo for T where T: const Specialize {}
    |                                  ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/const-traits/fn-ptr-lub.rs b/tests/ui/traits/const-traits/fn-ptr-lub.rs
new file mode 100644
index 00000000000..0fc32678827
--- /dev/null
+++ b/tests/ui/traits/const-traits/fn-ptr-lub.rs
@@ -0,0 +1,20 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+const fn foo() {}
+const fn bar() {}
+fn baz() {}
+
+const fn caller(branch: bool) {
+    let mut x = if branch {
+      foo
+    } else {
+      bar
+    };
+    x = baz;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/fn-ptr-lub.stderr b/tests/ui/traits/const-traits/fn-ptr-lub.stderr
new file mode 100644
index 00000000000..b333311b660
--- /dev/null
+++ b/tests/ui/traits/const-traits/fn-ptr-lub.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/fn-ptr-lub.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/hir-const-check.rs b/tests/ui/traits/const-traits/hir-const-check.rs
index f5fb0fd516a..b3df6495afc 100644
--- a/tests/ui/traits/const-traits/hir-const-check.rs
+++ b/tests/ui/traits/const-traits/hir-const-check.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Znext-solver
+
 // Regression test for #69615.
 
 #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
diff --git a/tests/ui/traits/const-traits/hir-const-check.stderr b/tests/ui/traits/const-traits/hir-const-check.stderr
index 598129d8694..19ea734efb7 100644
--- a/tests/ui/traits/const-traits/hir-const-check.stderr
+++ b/tests/ui/traits/const-traits/hir-const-check.stderr
@@ -1,5 +1,5 @@
 warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/hir-const-check.rs:3:30
+  --> $DIR/hir-const-check.rs:5:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^
@@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, effects)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0658]: `?` is not allowed in a `const fn`
-  --> $DIR/hir-const-check.rs:12:9
+  --> $DIR/hir-const-check.rs:14:9
    |
 LL |         Some(())?;
    |         ^^^^^^^^^
@@ -17,11 +17,6 @@ LL |         Some(())?;
    = help: add `#![feature(const_try)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
index 64634e7b7ac..29f40604747 100644
--- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
+++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
@@ -3,5 +3,6 @@
 
 const fn with_positive<F: ~const Fn()>() {}
 //~^ ERROR `~const` can only be applied to `#[const_trait]` traits
+//~| ERROR `~const` can only be applied to `#[const_trait]` traits
 
 pub fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
index c937430a1ca..03f88be0093 100644
--- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
+++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
@@ -9,5 +9,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn with_positive<F: ~const Fn()>() {}
    |                                  ^^^^
 
-error: aborting due to 2 previous errors
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/ice-123664-unexpected-bound-var.rs:4:34
+   |
+LL | const fn with_positive<F: ~const Fn()>() {}
+   |                                  ^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/traits/const-traits/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr
index ecc994a3fe6..805cc537014 100644
--- a/tests/ui/traits/const-traits/issue-92111.stderr
+++ b/tests/ui/traits/const-traits/issue-92111.stderr
@@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn a<T: ~const Destruct>(t: T) {}
    |                      ^^^^^^^^
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/issue-92111.rs:20:22
+   |
+LL | const fn a<T: ~const Destruct>(t: T) {}
+   |                      ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
   --> $DIR/issue-92111.rs:20:32
    |
@@ -12,6 +20,6 @@ LL | const fn a<T: ~const Destruct>(t: T) {}
    |                                |
    |                                the destructor for this type cannot be evaluated in constant functions
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.rs b/tests/ui/traits/const-traits/item-bound-entailment-fails.rs
new file mode 100644
index 00000000000..42799e3700c
--- /dev/null
+++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.rs
@@ -0,0 +1,31 @@
+//@ compile-flags: -Znext-solver
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Foo {
+    type Assoc<T>: ~const Bar
+    where
+        T: ~const Bar;
+}
+
+#[const_trait] trait Bar {}
+struct N<T>(T);
+impl<T> Bar for N<T> where T: Bar {}
+struct C<T>(T);
+impl<T> const Bar for C<T> where T: ~const Bar {}
+
+impl const Foo for u32 {
+    type Assoc<T> = N<T>
+    //~^ ERROR the trait bound `N<T>: ~const Bar` is not satisfied
+    where
+        T: ~const Bar;
+}
+
+impl const Foo for i32 {
+    type Assoc<T> = C<T>
+    //~^ ERROR the trait bound `T: ~const Bar` is not satisfied
+    where
+        T: Bar;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
new file mode 100644
index 00000000000..3b3868c4bc8
--- /dev/null
+++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
@@ -0,0 +1,36 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/item-bound-entailment-fails.rs:2:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `N<T>: ~const Bar` is not satisfied
+  --> $DIR/item-bound-entailment-fails.rs:18:21
+   |
+LL |     type Assoc<T> = N<T>
+   |                     ^^^^
+   |
+note: required by a bound in `Foo::Assoc`
+  --> $DIR/item-bound-entailment-fails.rs:6:20
+   |
+LL |     type Assoc<T>: ~const Bar
+   |                    ^^^^^^^^^^ required by this bound in `Foo::Assoc`
+
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
+  --> $DIR/item-bound-entailment-fails.rs:25:21
+   |
+LL |     type Assoc<T> = C<T>
+   |                     ^^^^
+   |
+note: required by a bound in `Foo::Assoc`
+  --> $DIR/item-bound-entailment-fails.rs:6:20
+   |
+LL |     type Assoc<T>: ~const Bar
+   |                    ^^^^^^^^^^ required by this bound in `Foo::Assoc`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/item-bound-entailment.rs b/tests/ui/traits/const-traits/item-bound-entailment.rs
new file mode 100644
index 00000000000..3670eabd66c
--- /dev/null
+++ b/tests/ui/traits/const-traits/item-bound-entailment.rs
@@ -0,0 +1,31 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Foo {
+    type Assoc<T>: ~const Bar
+    where
+        T: ~const Bar;
+}
+
+#[const_trait] trait Bar {}
+struct N<T>(T);
+impl<T> Bar for N<T> where T: Bar {}
+struct C<T>(T);
+impl<T> const Bar for C<T> where T: ~const Bar {}
+
+impl Foo for u32 {
+    type Assoc<T> = N<T>
+    where
+        T: Bar;
+}
+
+impl const Foo for i32 {
+    type Assoc<T> = C<T>
+    where
+        T: ~const Bar;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/item-bound-entailment.stderr b/tests/ui/traits/const-traits/item-bound-entailment.stderr
new file mode 100644
index 00000000000..b4a4ebdbee2
--- /dev/null
+++ b/tests/ui/traits/const-traits/item-bound-entailment.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/item-bound-entailment.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr
index de4783bdb3f..2803c37646b 100644
--- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr
+++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr
@@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | impl<A, B> const Convert<B> for A where B: ~const From<A> {
    |                                                   ^^^^^^^
 
-error[E0049]: method `to` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/non-const-op-in-closure-in-const.rs:5:1
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/non-const-op-in-closure-in-const.rs:10:51
+   |
+LL | impl<A, B> const Convert<B> for A where B: ~const From<A> {
+   |                                                   ^^^^^^^
    |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Convert<T> {
-LL |     fn to(self) -> T;
-   |          - expected 0 const parameters
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0015]: cannot call non-const fn `<B as From<A>>::from` in constant functions
   --> $DIR/non-const-op-in-closure-in-const.rs:12:9
@@ -27,5 +26,4 @@ LL + #![feature(effects)]
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.rs b/tests/ui/traits/const-traits/predicate-entailment-fails.rs
new file mode 100644
index 00000000000..5d6109bfad3
--- /dev/null
+++ b/tests/ui/traits/const-traits/predicate-entailment-fails.rs
@@ -0,0 +1,43 @@
+//@ compile-flags: -Znext-solver
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Bar {}
+impl const Bar for () {}
+
+
+#[const_trait] trait TildeConst {
+    type Bar<T> where T: ~const Bar;
+
+    fn foo<T>() where T: ~const Bar;
+}
+impl TildeConst for () {
+    type Bar<T> = () where T: const Bar;
+    //~^ ERROR impl has stricter requirements than trait
+
+    fn foo<T>() where T: const Bar {}
+    //~^ ERROR impl has stricter requirements than trait
+}
+
+
+#[const_trait] trait NeverConst {
+    type Bar<T> where T: Bar;
+
+    fn foo<T>() where T: Bar;
+}
+impl NeverConst for i32 {
+    type Bar<T> = () where T: const Bar;
+    //~^ ERROR impl has stricter requirements than trait
+
+    fn foo<T>() where T: const Bar {}
+    //~^ ERROR impl has stricter requirements than trait
+}
+impl const NeverConst for u32 {
+    type Bar<T> = () where T: ~const Bar;
+    //~^ ERROR impl has stricter requirements than trait
+
+    fn foo<T>() where T: ~const Bar {}
+    //~^ ERROR impl has stricter requirements than trait
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.stderr b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
new file mode 100644
index 00000000000..7cd48ef1d48
--- /dev/null
+++ b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
@@ -0,0 +1,66 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/predicate-entailment-fails.rs:2:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/predicate-entailment-fails.rs:15:31
+   |
+LL |     type Bar<T> where T: ~const Bar;
+   |     ----------- definition of `Bar` from trait
+...
+LL |     type Bar<T> = () where T: const Bar;
+   |                               ^^^^^^^^^ impl has extra requirement `T: const Bar`
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/predicate-entailment-fails.rs:18:26
+   |
+LL |     fn foo<T>() where T: ~const Bar;
+   |     -------------------------------- definition of `foo` from trait
+...
+LL |     fn foo<T>() where T: const Bar {}
+   |                          ^^^^^^^^^ impl has extra requirement `T: const Bar`
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/predicate-entailment-fails.rs:29:31
+   |
+LL |     type Bar<T> where T: Bar;
+   |     ----------- definition of `Bar` from trait
+...
+LL |     type Bar<T> = () where T: const Bar;
+   |                               ^^^^^^^^^ impl has extra requirement `T: const Bar`
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/predicate-entailment-fails.rs:32:26
+   |
+LL |     fn foo<T>() where T: Bar;
+   |     ------------------------- definition of `foo` from trait
+...
+LL |     fn foo<T>() where T: const Bar {}
+   |                          ^^^^^^^^^ impl has extra requirement `T: const Bar`
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/predicate-entailment-fails.rs:36:31
+   |
+LL |     type Bar<T> where T: Bar;
+   |     ----------- definition of `Bar` from trait
+...
+LL |     type Bar<T> = () where T: ~const Bar;
+   |                               ^^^^^^^^^^ impl has extra requirement `T: ~const Bar`
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/predicate-entailment-fails.rs:39:26
+   |
+LL |     fn foo<T>() where T: Bar;
+   |     ------------------------- definition of `foo` from trait
+...
+LL |     fn foo<T>() where T: ~const Bar {}
+   |                          ^^^^^^^^^^ impl has extra requirement `T: ~const Bar`
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/traits/const-traits/predicate-entailment-passes.rs b/tests/ui/traits/const-traits/predicate-entailment-passes.rs
new file mode 100644
index 00000000000..b660329151b
--- /dev/null
+++ b/tests/ui/traits/const-traits/predicate-entailment-passes.rs
@@ -0,0 +1,39 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+#[const_trait] trait Bar {}
+impl const Bar for () {}
+
+
+#[const_trait] trait TildeConst {
+    type Bar<T> where T: ~const Bar;
+
+    fn foo<T>() where T: ~const Bar;
+}
+impl TildeConst for () {
+    type Bar<T> = () where T: Bar;
+
+    fn foo<T>() where T: Bar {}
+}
+
+
+#[const_trait] trait AlwaysConst {
+    type Bar<T> where T: const Bar;
+
+    fn foo<T>() where T: const Bar;
+}
+impl AlwaysConst for i32 {
+    type Bar<T> = () where T: Bar;
+
+    fn foo<T>() where T: Bar {}
+}
+impl const AlwaysConst for u32 {
+    type Bar<T> = () where T: ~const Bar;
+
+    fn foo<T>() where T: ~const Bar {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/predicate-entailment-passes.stderr b/tests/ui/traits/const-traits/predicate-entailment-passes.stderr
new file mode 100644
index 00000000000..dcaeea73b58
--- /dev/null
+++ b/tests/ui/traits/const-traits/predicate-entailment-passes.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/predicate-entailment-passes.rs:4:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr
index 7643697874f..bffc60c65fc 100644
--- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr
+++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -1,12 +1,3 @@
-error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-default-bound-non-const-specialized-bound.rs:16:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Bar {
-LL |     fn bar();
-   |           - expected 0 const parameters
-
 error: cannot specialize on const impl with non-const impl
   --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:1
    |
@@ -16,26 +7,5 @@ LL | |     T: Foo, //FIXME ~ ERROR missing `~const` qualifier
 LL | |     T: Specialize,
    | |__________________^
 
-error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Baz {
-LL |     fn baz();
-   |           - expected 0 const parameters
-
-error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Baz {
-LL |     fn baz();
-   |           - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr
index 9b2ae8d739c..f127268d2a1 100644
--- a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr
+++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr
@@ -1,23 +1,3 @@
-error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-default-const-specialized.rs:10:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Value {
-LL |     fn value() -> u32;
-   |             - expected 0 const parameters
-
-error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/const-default-const-specialized.rs:10:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Value {
-LL |     fn value() -> u32;
-   |             - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0015]: cannot call non-const fn `<T as Value>::value` in constant functions
   --> $DIR/const-default-const-specialized.rs:16:5
    |
@@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.rs b/tests/ui/traits/const-traits/specialization/default-keyword.rs
index d9ffd237dce..bc45a70777c 100644
--- a/tests/ui/traits/const-traits/specialization/default-keyword.rs
+++ b/tests/ui/traits/const-traits/specialization/default-keyword.rs
@@ -1,5 +1,4 @@
-//@ known-bug: #110395
-// FIXME check-pass
+//@ check-pass
 
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.stderr b/tests/ui/traits/const-traits/specialization/default-keyword.stderr
deleted file mode 100644
index 18a25045f4b..00000000000
--- a/tests/ui/traits/const-traits/specialization/default-keyword.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/default-keyword.rs:7:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Foo {
-LL |     fn foo();
-   |           - expected 0 const parameters
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
index 219e5f3a600..d80370aee82 100644
--- a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
+++ b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -1,7 +1,6 @@
 // Tests that `~const` trait bounds can be used to specialize const trait impls.
 
-//@ known-bug: #110395
-// FIXME check-pass
+//@ check-pass
 
 #![feature(const_trait_impl)]
 #![feature(rustc_attrs)]
diff --git a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr
deleted file mode 100644
index ecdc7b930e6..00000000000
--- a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr
+++ /dev/null
@@ -1,43 +0,0 @@
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Foo {
-LL |     fn foo();
-   |           - expected 0 const parameters
-
-error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Foo {
-LL |     fn foo();
-   |           - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Bar {
-LL |     fn bar() {}
-   |           - expected 0 const parameters
-
-error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Bar {
-LL |     fn bar() {}
-   |           - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
index 7514baa2fd5..d97469edaf9 100644
--- a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -2,8 +2,7 @@
 // `T: Foo` in the default impl for the purposes of specialization (i.e., it
 // does not think that the user is attempting to specialize on trait `Foo`).
 
-//@ known-bug: #110395
-// FIXME check-pass
+//@ check-pass
 
 #![feature(rustc_attrs)]
 #![feature(min_specialization)]
diff --git a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr
deleted file mode 100644
index 6679bb46537..00000000000
--- a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr
+++ /dev/null
@@ -1,43 +0,0 @@
-error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Bar {
-LL |     fn bar();
-   |           - expected 0 const parameters
-
-error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Bar {
-LL |     fn bar();
-   |           - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Baz {
-LL |     fn baz();
-   |           - expected 0 const parameters
-
-error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Baz {
-LL |     fn baz();
-   |           - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr
index 7f363922947..a4095d7e8ce 100644
--- a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr
+++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr
@@ -1,23 +1,3 @@
-error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/non-const-default-const-specialized.rs:9:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Value {
-LL |     fn value() -> u32;
-   |             - expected 0 const parameters
-
-error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/non-const-default-const-specialized.rs:9:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | trait Value {
-LL |     fn value() -> u32;
-   |             - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0015]: cannot call non-const fn `<T as Value>::value` in constant functions
   --> $DIR/non-const-default-const-specialized.rs:15:5
    |
@@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr
index bf273f349b4..8e6f6945a1b 100644
--- a/tests/ui/traits/const-traits/specializing-constness-2.stderr
+++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr
@@ -1,23 +1,3 @@
-error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/specializing-constness-2.rs:9:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub trait A {
-LL |     fn a() -> u32;
-   |         - expected 0 const parameters
-
-error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
-  --> $DIR/specializing-constness-2.rs:9:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ found 1 const parameter
-LL | pub trait A {
-LL |     fn a() -> u32;
-   |         - expected 0 const parameters
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
   --> $DIR/specializing-constness-2.rs:27:5
    |
@@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0015, E0049.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs
index 4501a218ad7..3aabaf137d5 100644
--- a/tests/ui/traits/const-traits/specializing-constness.rs
+++ b/tests/ui/traits/const-traits/specializing-constness.rs
@@ -22,8 +22,6 @@ impl<T: ~const Spec> const A for T {
 
 impl<T: Spec + Sup> A for T {
 //~^ ERROR: cannot specialize
-//~| ERROR: cannot specialize
-//~| ERROR: cannot specialize
 //FIXME(effects) ~| ERROR: missing `~const` qualifier
     fn a() -> u32 {
         3
diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr
index 90721af8e5a..e8c4fb0f0c7 100644
--- a/tests/ui/traits/const-traits/specializing-constness.stderr
+++ b/tests/ui/traits/const-traits/specializing-constness.stderr
@@ -18,17 +18,5 @@ error: cannot specialize on const impl with non-const impl
 LL | impl<T: Spec + Sup> A for T {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: cannot specialize on trait `Compat`
-  --> $DIR/specializing-constness.rs:23:16
-   |
-LL | impl<T: Spec + Sup> A for T {
-   |                ^^^
-
-error: cannot specialize on trait `Compat`
-  --> $DIR/specializing-constness.rs:23:9
-   |
-LL | impl<T: Spec + Sup> A for T {
-   |         ^^^^
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr
index 029c3b4bde3..a0848fe520e 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr
@@ -20,5 +20,21 @@ LL | trait Bar: ~const Foo {}
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 3 previous errors
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:12:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:12:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.rs b/tests/ui/traits/const-traits/super-traits-fail-2.rs
index 93a6f385e47..0ea61f4ae20 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-2.rs
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.rs
@@ -13,7 +13,9 @@ trait Bar: ~const Foo {}
 //[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]`
 //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]`
 //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]`
-//[yn,nn]~^^^^ ERROR: `~const` is not allowed here
+//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]`
+//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]`
+//[yn,nn]~^^^^^^ ERROR: `~const` is not allowed here
 
 const fn foo<T: Bar>(x: &T) {
     x.a();
diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr
index 873c57ec71f..ec6ca107289 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr
@@ -11,23 +11,10 @@ LL | trait Bar: ~const Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-2.rs:19:7
+  --> $DIR/super-traits-fail-2.rs:21:5
    |
 LL |     x.a();
-   |       ^ the trait `Foo` is not implemented for `T`
-   |
-note: required by a bound in `Foo::a`
-  --> $DIR/super-traits-fail-2.rs:6:25
-   |
-LL | #[cfg_attr(any(yy, yn), const_trait)]
-   |                         ^^^^^^^^^^^ required by this bound in `Foo::a`
-LL | trait Foo {
-LL |     fn a(&self);
-   |        - required by a bound in this associated function
-help: consider further restricting this bound
-   |
-LL | const fn foo<T: Bar + Foo>(x: &T) {
-   |                     +++++
+   |     ^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr
index bea3aea2f3a..3fa6256abc3 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr
@@ -1,21 +1,8 @@
 error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-2.rs:19:7
+  --> $DIR/super-traits-fail-2.rs:21:5
    |
 LL |     x.a();
-   |       ^ the trait `Foo` is not implemented for `T`
-   |
-note: required by a bound in `Foo::a`
-  --> $DIR/super-traits-fail-2.rs:6:25
-   |
-LL | #[cfg_attr(any(yy, yn), const_trait)]
-   |                         ^^^^^^^^^^^ required by this bound in `Foo::a`
-LL | trait Foo {
-LL |     fn a(&self);
-   |        - required by a bound in this associated function
-help: consider further restricting this bound
-   |
-LL | const fn foo<T: Bar + Foo>(x: &T) {
-   |                     +++++
+   |     ^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr
index f40583f0ca5..294545014bf 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr
@@ -33,10 +33,18 @@ LL | trait Bar: ~const Foo {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/super-traits-fail-3.rs:20:24
+  --> $DIR/super-traits-fail-3.rs:22:24
    |
 LL | const fn foo<T: ~const Bar>(x: &T) {
    |                        ^^^
 
-error: aborting due to 5 previous errors
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:22:24
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                        ^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr
index 3f6dfa7b008..54bb6c5ca44 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr
@@ -20,5 +20,21 @@ LL | trait Bar: ~const Foo {}
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 3 previous errors
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:14:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:14:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs
index b5643b11700..a9b08e6edcd 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-3.rs
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs
@@ -15,10 +15,13 @@ trait Bar: ~const Foo {}
 //[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]`
 //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]`
 //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]`
-//[yn,nn]~^^^^ ERROR: `~const` is not allowed here
+//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]`
+//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]`
+//[yn,nn]~^^^^^^ ERROR: `~const` is not allowed here
 
 const fn foo<T: ~const Bar>(x: &T) {
     //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]`
+    //[yn,nn]~| ERROR: `~const` can only be applied to `#[const_trait]`
     x.a();
     //[yn]~^ ERROR: the trait bound `T: ~const Foo` is not satisfied
 }
diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr
index bbc95948a59..b6747d10e83 100644
--- a/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr
@@ -11,30 +11,25 @@ LL | trait Bar: ~const Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/super-traits-fail-3.rs:20:24
+  --> $DIR/super-traits-fail-3.rs:22:24
    |
 LL | const fn foo<T: ~const Bar>(x: &T) {
    |                        ^^^
 
-error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-3.rs:22:7
-   |
-LL |     x.a();
-   |       ^ the trait `Foo` is not implemented for `T`
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:22:24
    |
-note: required by a bound in `Foo::a`
-  --> $DIR/super-traits-fail-3.rs:8:25
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                        ^^^
    |
-LL | #[cfg_attr(any(yy, yn), const_trait)]
-   |                         ^^^^^^^^^^^ required by this bound in `Foo::a`
-LL | trait Foo {
-LL |     fn a(&self);
-   |        - required by a bound in this associated function
-help: consider further restricting this bound
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-3.rs:25:5
    |
-LL | const fn foo<T: ~const Bar + Foo>(x: &T) {
-   |                            +++++
+LL |     x.a();
+   |     ^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/super-traits-fail.rs b/tests/ui/traits/const-traits/super-traits-fail.rs
index da41d7fcc72..c07619fbf62 100644
--- a/tests/ui/traits/const-traits/super-traits-fail.rs
+++ b/tests/ui/traits/const-traits/super-traits-fail.rs
@@ -1,4 +1,3 @@
-//~ ERROR the trait bound
 //@ compile-flags: -Znext-solver
 
 #![allow(incomplete_features)]
diff --git a/tests/ui/traits/const-traits/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr
index 3870f0f722f..7a734a6c9f1 100644
--- a/tests/ui/traits/const-traits/super-traits-fail.stderr
+++ b/tests/ui/traits/const-traits/super-traits-fail.stderr
@@ -1,24 +1,9 @@
-error[E0277]: the trait bound `Bar::{synthetic#0}: TyCompat<Foo::{synthetic#0}>` is not satisfied
-  --> $DIR/super-traits-fail.rs:19:12
+error[E0277]: the trait bound `S: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail.rs:18:20
    |
 LL | impl const Bar for S {}
-   |            ^^^ the trait `TyCompat<Foo::{synthetic#0}>` is not implemented for `Bar::{synthetic#0}`, which is required by `S: Bar`
-   |
-   = help: the trait `Bar` is implemented for `S`
-note: required for `S` to implement `Bar`
-  --> $DIR/super-traits-fail.rs:12:7
-   |
-LL | trait Bar: ~const Foo {}
-   |       ^^^
-
-error[E0277]: the trait bound `Maybe: TyCompat<Foo::{synthetic#0}>` is not satisfied
-   |
-note: required by a bound in `Bar::{synthetic#0}`
-  --> $DIR/super-traits-fail.rs:12:12
-   |
-LL | trait Bar: ~const Foo {}
-   |            ^^^^^^^^^^ required by this bound in `Bar::{synthetic#0}`
+   |                    ^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/tilde-const-and-const-params.rs b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs
index 4b720b534a4..f6a7c7c1746 100644
--- a/tests/ui/traits/const-traits/tilde-const-and-const-params.rs
+++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs
@@ -8,7 +8,6 @@ struct Foo<const N: usize>;
 impl<const N: usize> Foo<N> {
     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
         //~^ ERROR `~const` is not allowed here
-        //~| ERROR mismatched types
         Foo
     }
 }
@@ -26,7 +25,6 @@ impl const Add42 for () {
 
 fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
     //~^ ERROR `~const` is not allowed here
-    //~| ERROR mismatched types
     Foo
 }
 
diff --git a/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr
index 73526a26e08..84a425f6791 100644
--- a/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr
+++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr
@@ -11,13 +11,13 @@ LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
    |        ^^^
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-and-const-params.rs:27:11
+  --> $DIR/tilde-const-and-const-params.rs:26:11
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |           ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
-  --> $DIR/tilde-const-and-const-params.rs:27:4
+  --> $DIR/tilde-const-and-const-params.rs:26:4
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |    ^^^
@@ -27,24 +27,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
    = note: the next trait solver must be enabled globally for the effects feature to work correctly
    = help: use `-Znext-solver` to enable
 
-error[E0308]: mismatched types
-  --> $DIR/tilde-const-and-const-params.rs:27:61
-   |
-LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
-   |                                                             ^^^^^^^^^ expected `false`, found `true`
-   |
-   = note: expected constant `false`
-              found constant `true`
-
-error[E0308]: mismatched types
-  --> $DIR/tilde-const-and-const-params.rs:9:44
-   |
-LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
-   |                                            ^^^^^^^^^ expected `false`, found `true`
-   |
-   = note: expected constant `false`
-              found constant `true`
-
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/const-traits/tilde-const-in-struct-args.rs b/tests/ui/traits/const-traits/tilde-const-in-struct-args.rs
new file mode 100644
index 00000000000..4722be955e9
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-in-struct-args.rs
@@ -0,0 +1,21 @@
+//@ compile-flags: -Znext-solver
+//@ known-bug: #132067
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+
+struct S;
+#[const_trait]
+trait Trait<const N: u32> {}
+
+const fn f<
+    T: Trait<
+        {
+            struct I<U: ~const Trait<0>>(U);
+            0
+        },
+    >,
+>() {
+}
+
+pub fn main() {}
diff --git a/tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr b/tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr
new file mode 100644
index 00000000000..a9759f10d06
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr
@@ -0,0 +1,11 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/tilde-const-in-struct-args.rs:5:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.rs b/tests/ui/traits/const-traits/trait-where-clause-const.rs
index 8ca9b7cc7aa..61e2bc38426 100644
--- a/tests/ui/traits/const-traits/trait-where-clause-const.rs
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.rs
@@ -20,11 +20,9 @@ trait Foo {
 const fn test1<T: ~const Foo + Bar>() {
     T::a();
     T::b();
-    //~^ ERROR mismatched types
-    //~| ERROR the trait bound
+    //~^ ERROR the trait bound
     T::c::<T>();
-    //~^ ERROR mismatched types
-    //~| ERROR the trait bound
+    //~^ ERROR the trait bound
 }
 
 const fn test2<T: ~const Foo + ~const Bar>() {
diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
index eaa981ec744..30a7ef1fd0d 100644
--- a/tests/ui/traits/const-traits/trait-where-clause-const.stderr
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
@@ -1,52 +1,15 @@
-error[E0277]: the trait bound `T: Foo` is not satisfied
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/trait-where-clause-const.rs:22:5
    |
 LL |     T::b();
-   |     ^ the trait `Foo` is not implemented for `T`
-   |
-note: required by a bound in `Foo::b`
-  --> $DIR/trait-where-clause-const.rs:13:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Foo::b`
-...
-LL |     fn b() where Self: ~const Bar;
-   |        - required by a bound in this associated function
-
-error[E0308]: mismatched types
-  --> $DIR/trait-where-clause-const.rs:22:5
-   |
-LL |     T::b();
-   |     ^^^^^^ expected `host`, found `true`
-   |
-   = note: expected constant `host`
-              found constant `true`
+   |     ^^^^^^
 
-error[E0277]: the trait bound `T: Foo` is not satisfied
-  --> $DIR/trait-where-clause-const.rs:25:5
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
+  --> $DIR/trait-where-clause-const.rs:24:5
    |
 LL |     T::c::<T>();
-   |     ^ the trait `Foo` is not implemented for `T`
-   |
-note: required by a bound in `Foo::c`
-  --> $DIR/trait-where-clause-const.rs:13:1
-   |
-LL | #[const_trait]
-   | ^^^^^^^^^^^^^^ required by this bound in `Foo::c`
-...
-LL |     fn c<T: ~const Bar>();
-   |        - required by a bound in this associated function
-
-error[E0308]: mismatched types
-  --> $DIR/trait-where-clause-const.rs:25:5
-   |
-LL |     T::c::<T>();
-   |     ^^^^^^^^^^^ expected `host`, found `true`
-   |
-   = note: expected constant `host`
-              found constant `true`
+   |     ^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0308.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
index 848aa68689b..e0cf062ad95 100644
--- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
@@ -6,41 +6,30 @@ LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
    |
    = help: remove one of these features
 
-error[E0308]: mismatched types
+error[E0277]: the trait bound `T: const Trait` is not satisfied
   --> $DIR/unsatisfied-const-trait-bound.rs:29:37
    |
 LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
-   |                                     ^^^^^^^^^ expected `false`, found `true`
-   |
-   = note: expected constant `false`
-              found constant `true`
+   |                                     ^^^^^^^^^
 
-error[E0308]: mismatched types
+error[E0277]: the trait bound `T: const Trait` is not satisfied
   --> $DIR/unsatisfied-const-trait-bound.rs:33:50
    |
 LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
-   |                                                  ^^^^^^^^^ expected `false`, found `host`
-   |
-   = note: expected constant `false`
-              found constant `host`
+   |                                                  ^^^^^^^^^
 
 error[E0277]: the trait bound `Ty: const Trait` is not satisfied
-  --> $DIR/unsatisfied-const-trait-bound.rs:22:15
+  --> $DIR/unsatisfied-const-trait-bound.rs:22:5
    |
 LL |     require::<Ty>();
-   |               ^^ the trait `Trait` is not implemented for `Ty`
+   |     ^^^^^^^^^^^^^^^
    |
 note: required by a bound in `require`
   --> $DIR/unsatisfied-const-trait-bound.rs:8:15
    |
 LL | fn require<T: const Trait>() {}
    |               ^^^^^^^^^^^ required by this bound in `require`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() where Ty: Trait {
-   |           +++++++++++++++
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0277, E0308.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.