about summary refs log tree commit diff
path: root/tests/ui/traits
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-10-22 00:03:09 +0000
committerMichael Goulet <michael@errs.io>2024-10-22 00:03:09 +0000
commite91267f3f094a6f5d16aef0abb864fca4bc8c9f4 (patch)
treeba5ce9ae085572e299066b12a06da711416eea87 /tests/ui/traits
parentedbd9398dcc0e3b6ffe0dd0cd4578d37d1d36974 (diff)
downloadrust-e91267f3f094a6f5d16aef0abb864fca4bc8c9f4.tar.gz
rust-e91267f3f094a6f5d16aef0abb864fca4bc8c9f4.zip
Move tests
Diffstat (limited to 'tests/ui/traits')
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs20
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr46
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs23
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr46
-rw-r--r--tests/ui/traits/const-traits/assoc-type.rs48
-rw-r--r--tests/ui/traits/const-traits/assoc-type.stderr16
-rw-r--r--tests/ui/traits/const-traits/attr-misuse.rs10
-rw-r--r--tests/ui/traits/const-traits/attr-misuse.stderr18
-rw-r--r--tests/ui/traits/const-traits/auxiliary/cross-crate.rs25
-rw-r--r--tests/ui/traits/const-traits/auxiliary/staged-api.rs21
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-fail.rs31
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-fail.stderr22
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.rs43
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.stderr79
-rw-r--r--tests/ui/traits/const-traits/call-generic-in-impl.rs16
-rw-r--r--tests/ui/traits/const-traits/call-generic-in-impl.stderr31
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-chain.rs29
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-chain.stderr37
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-dup-bound.rs32
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr37
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-fail.rs12
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs17
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.rs28
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.stderr21
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-pass.rs25
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-pass.stderr31
-rw-r--r--tests/ui/traits/const-traits/call.rs10
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.rs31
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.stderr44
-rw-r--r--tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs29
-rw-r--r--tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr31
-rw-r--r--tests/ui/traits/const-traits/const-bounds-non-const-trait.rs12
-rw-r--r--tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr28
-rw-r--r--tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs16
-rw-r--r--tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr25
-rw-r--r--tests/ui/traits/const-traits/const-closure-parse-not-item.rs11
-rw-r--r--tests/ui/traits/const-traits/const-closure-parse-not-item.stderr16
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method-fail.rs20
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr35
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.rs20
-rw-r--r--tests/ui/traits/const-traits/const-closure-trait-method.stderr35
-rw-r--r--tests/ui/traits/const-traits/const-closures.rs31
-rw-r--r--tests/ui/traits/const-traits/const-closures.stderr75
-rw-r--r--tests/ui/traits/const-traits/const-default-method-bodies.rs31
-rw-r--r--tests/ui/traits/const-traits/const-default-method-bodies.stderr22
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.rs26
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.stderr27
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr26
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.rs45
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stderr39
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr26
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.precise.stderr77
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.rs36
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.stock.stderr26
-rw-r--r--tests/ui/traits/const-traits/const-drop.precise.stderr84
-rw-r--r--tests/ui/traits/const-traits/const-drop.rs115
-rw-r--r--tests/ui/traits/const-traits/const-drop.stock.stderr86
-rw-r--r--tests/ui/traits/const-traits/const-fns-are-early-bound.rs136
-rw-r--r--tests/ui/traits/const-traits/const-fns-are-early-bound.stderr20
-rw-r--r--tests/ui/traits/const-traits/const-impl-norecover.rs12
-rw-r--r--tests/ui/traits/const-traits/const-impl-norecover.stderr8
-rw-r--r--tests/ui/traits/const-traits/const-impl-recovery.rs17
-rw-r--r--tests/ui/traits/const-traits/const-impl-recovery.stderr26
-rw-r--r--tests/ui/traits/const-traits/const-impl-requires-const-trait.rs11
-rw-r--r--tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr28
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.rs56
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.stderr249
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs18
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr30
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds.rs32
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds.stderr29
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-gate.rs5
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr22
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs13
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr26
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.rs20
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.stderr90
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs14
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr34
-rw-r--r--tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs19
-rw-r--r--tests/ui/traits/const-traits/cross-crate.gatednc.stderr22
-rw-r--r--tests/ui/traits/const-traits/cross-crate.rs27
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stock.stderr15
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stocknc.stderr27
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs20
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs17
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr22
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs17
-rw-r--r--tests/ui/traits/const-traits/do-not-const-check-override.rs21
-rw-r--r--tests/ui/traits/const-traits/do-not-const-check.rs18
-rw-r--r--tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs14
-rw-r--r--tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs18
-rw-r--r--tests/ui/traits/const-traits/effects/effect-param-infer.rs16
-rw-r--r--tests/ui/traits/const-traits/effects/fallback.rs17
-rw-r--r--tests/ui/traits/const-traits/effects/group-traits.rs14
-rw-r--r--tests/ui/traits/const-traits/effects/helloworld.rs33
-rw-r--r--tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs19
-rw-r--r--tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr51
-rw-r--r--tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs18
-rw-r--r--tests/ui/traits/const-traits/effects/infer-fallback.rs13
-rw-r--r--tests/ui/traits/const-traits/effects/minicore.rs570
-rw-r--r--tests/ui/traits/const-traits/effects/minicore.stderr13
-rw-r--r--tests/ui/traits/const-traits/effects/mismatched_generic_args.rs24
-rw-r--r--tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr64
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs18
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr63
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params.rs27
-rw-r--r--tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr87
-rw-r--r--tests/ui/traits/const-traits/effects/project.rs14
-rw-r--r--tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs14
-rw-r--r--tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr50
-rw-r--r--tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs21
-rw-r--r--tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr64
-rw-r--r--tests/ui/traits/const-traits/effects/trait-fn-const.rs21
-rw-r--r--tests/ui/traits/const-traits/effects/trait-fn-const.stderr73
-rw-r--r--tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr7
-rw-r--r--tests/ui/traits/const-traits/effects/with-without-next-solver.rs10
-rw-r--r--tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr7
-rw-r--r--tests/ui/traits/const-traits/feature-gate.gated.stderr8
-rw-r--r--tests/ui/traits/const-traits/feature-gate.rs22
-rw-r--r--tests/ui/traits/const-traits/feature-gate.stock.stderr63
-rw-r--r--tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs15
-rw-r--r--tests/ui/traits/const-traits/gate.rs13
-rw-r--r--tests/ui/traits/const-traits/gate.stderr23
-rw-r--r--tests/ui/traits/const-traits/generic-bound.rs30
-rw-r--r--tests/ui/traits/const-traits/generic-bound.stderr24
-rw-r--r--tests/ui/traits/const-traits/hir-const-check.rs17
-rw-r--r--tests/ui/traits/const-traits/hir-const-check.stderr27
-rw-r--r--tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs15
-rw-r--r--tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr38
-rw-r--r--tests/ui/traits/const-traits/ice-120503-async-const-method.rs17
-rw-r--r--tests/ui/traits/const-traits/ice-120503-async-const-method.stderr75
-rw-r--r--tests/ui/traits/const-traits/ice-121536-const-method.rs17
-rw-r--r--tests/ui/traits/const-traits/ice-121536-const-method.stderr33
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs7
-rw-r--r--tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr13
-rw-r--r--tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs14
-rw-r--r--tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr17
-rw-r--r--tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs28
-rw-r--r--tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr43
-rw-r--r--tests/ui/traits/const-traits/impl-tilde-const-trait.rs9
-rw-r--r--tests/ui/traits/const-traits/impl-tilde-const-trait.stderr8
-rw-r--r--tests/ui/traits/const-traits/impl-with-default-fn-fail.rs18
-rw-r--r--tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr17
-rw-r--r--tests/ui/traits/const-traits/impl-with-default-fn-pass.rs27
-rw-r--r--tests/ui/traits/const-traits/inherent-impl-const-bounds.rs22
-rw-r--r--tests/ui/traits/const-traits/inherent-impl.rs13
-rw-r--r--tests/ui/traits/const-traits/inherent-impl.stderr22
-rw-r--r--tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs32
-rw-r--r--tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr21
-rw-r--r--tests/ui/traits/const-traits/issue-100222.rs42
-rw-r--r--tests/ui/traits/const-traits/issue-102156.rs15
-rw-r--r--tests/ui/traits/const-traits/issue-102156.stderr23
-rw-r--r--tests/ui/traits/const-traits/issue-102985.rs13
-rw-r--r--tests/ui/traits/const-traits/issue-102985.stderr16
-rw-r--r--tests/ui/traits/const-traits/issue-103677.rs5
-rw-r--r--tests/ui/traits/const-traits/issue-79450.rs22
-rw-r--r--tests/ui/traits/const-traits/issue-79450.stderr12
-rw-r--r--tests/ui/traits/const-traits/issue-88155.rs15
-rw-r--r--tests/ui/traits/const-traits/issue-88155.stderr15
-rw-r--r--tests/ui/traits/const-traits/issue-92111.rs24
-rw-r--r--tests/ui/traits/const-traits/issue-92111.stderr17
-rw-r--r--tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs17
-rw-r--r--tests/ui/traits/const-traits/match-non-const-eq.gated.stderr16
-rw-r--r--tests/ui/traits/const-traits/match-non-const-eq.rs13
-rw-r--r--tests/ui/traits/const-traits/match-non-const-eq.stock.stderr16
-rw-r--r--tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs20
-rw-r--r--tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs21
-rw-r--r--tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr45
-rw-r--r--tests/ui/traits/const-traits/mbe-dyn-const-2015.rs13
-rw-r--r--tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs20
-rw-r--r--tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr46
-rw-r--r--tests/ui/traits/const-traits/nested-closure.rs12
-rw-r--r--tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs15
-rw-r--r--tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr15
-rw-r--r--tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs18
-rw-r--r--tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr31
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs56
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr41
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs40
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr36
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs26
-rw-r--r--tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr22
-rw-r--r--tests/ui/traits/const-traits/specialization/default-keyword.rs16
-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.rs50
-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.rs58
-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.rs39
-rw-r--r--tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr36
-rw-r--r--tests/ui/traits/const-traits/specializing-constness-2.rs31
-rw-r--r--tests/ui/traits/const-traits/specializing-constness-2.stderr36
-rw-r--r--tests/ui/traits/const-traits/specializing-constness.rs33
-rw-r--r--tests/ui/traits/const-traits/specializing-constness.stderr34
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.rs16
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.stderr15
-rw-r--r--tests/ui/traits/const-traits/staged-api.rs63
-rw-r--r--tests/ui/traits/const-traits/staged-api.stable.stderr49
-rw-r--r--tests/ui/traits/const-traits/staged-api.unstable.stderr42
-rw-r--r--tests/ui/traits/const-traits/static-const-trait-bound.rs18
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.gated.stderr22
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.rs21
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.stock.stderr15
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr36
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr24
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.rs23
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr34
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr22
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr42
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr24
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.rs26
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr40
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail.rs22
-rw-r--r--tests/ui/traits/const-traits/super-traits-fail.stderr24
-rw-r--r--tests/ui/traits/const-traits/super-traits.rs27
-rw-r--r--tests/ui/traits/const-traits/syntax.rs8
-rw-r--r--tests/ui/traits/const-traits/tilde-const-and-const-params.rs37
-rw-r--r--tests/ui/traits/const-traits/tilde-const-and-const-params.stderr50
-rw-r--r--tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs30
-rw-r--r--tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs19
-rw-r--r--tests/ui/traits/const-traits/tilde-const-invalid-places.rs61
-rw-r--r--tests/ui/traits/const-traits/tilde-const-invalid-places.stderr310
-rw-r--r--tests/ui/traits/const-traits/tilde-const-syntax.rs9
-rw-r--r--tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs20
-rw-r--r--tests/ui/traits/const-traits/tilde-twice.rs6
-rw-r--r--tests/ui/traits/const-traits/tilde-twice.stderr8
-rw-r--r--tests/ui/traits/const-traits/trait-default-body-stability.rs51
-rw-r--r--tests/ui/traits/const-traits/trait-default-body-stability.stderr20
-rw-r--r--tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs23
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.rs36
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.stderr52
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-run.rs43
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-self-referential.rs25
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause.rs28
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause.stderr59
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs33
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr46
238 files changed, 7896 insertions, 0 deletions
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
new file mode 100644
index 00000000000..4399ae2d1be
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
@@ -0,0 +1,20 @@
+//@ known-bug: unknown
+
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Trait {
+    type Assoc: ~const Trait;
+    fn func() -> i32;
+}
+
+const fn unqualified<T: ~const Trait>() -> i32 {
+    T::Assoc::func()
+}
+
+const fn qualified<T: ~const Trait>() -> i32 {
+    <T as Trait>::Assoc::func()
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..8288c660ce7
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
@@ -0,0 +1,46 @@
+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
+   |
+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 {
+   |                                                ++++++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-0.rs:17: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 {
+   |                                              ++++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
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
new file mode 100644
index 00000000000..8a1bf75f87e
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs
@@ -0,0 +1,23 @@
+//@ known-bug: unknown
+// FIXME(effects)
+
+#![feature(const_trait_impl, effects, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+#[const_trait]
+trait Trait {
+    type Assoc: ~const Trait;
+    fn func() -> i32;
+}
+
+struct Type<const N: i32>;
+
+fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
+    Type
+}
+
+fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> {
+    Type
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..0792d090321
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
@@ -0,0 +1,46 @@
+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-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 {
+   |                                                                ++++++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
+  --> $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 {
+   |                                                                         ++++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/assoc-type.rs b/tests/ui/traits/const-traits/assoc-type.rs
new file mode 100644
index 00000000000..ea3cbabf302
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type.rs
@@ -0,0 +1,48 @@
+// FIXME(effects): Replace `Add` with `std::ops::Add` once the latter a `#[const_trait]` again.
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+#[const_trait]
+trait Add<Rhs = Self> {
+    type Output;
+
+    fn add(self, other: Rhs) -> Self::Output;
+}
+
+impl const Add for i32 {
+    type Output = Self;
+
+    fn add(self, other: Self) -> Self::Output {
+        self + other
+    }
+}
+
+struct NonConstAdd(i32);
+
+impl Add for NonConstAdd {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        NonConstAdd(self.0.add(rhs.0))
+    }
+}
+
+#[const_trait]
+trait Foo {
+    type Bar: ~const Add;
+}
+
+impl const Foo for NonConstAdd {
+    type Bar = NonConstAdd;
+    // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied
+}
+
+#[const_trait]
+trait Baz {
+    type Qux: Add;
+}
+
+impl const Baz for NonConstAdd {
+    type Qux = NonConstAdd; // OK
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/assoc-type.stderr b/tests/ui/traits/const-traits/assoc-type.stderr
new file mode 100644
index 00000000000..c20b53c210f
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type.stderr
@@ -0,0 +1,16 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/assoc-type.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: 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 1 previous error; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/attr-misuse.rs b/tests/ui/traits/const-traits/attr-misuse.rs
new file mode 100644
index 00000000000..01ac74feff7
--- /dev/null
+++ b/tests/ui/traits/const-traits/attr-misuse.rs
@@ -0,0 +1,10 @@
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait A {
+    #[const_trait] //~ ERROR attribute should be applied
+    fn foo(self);
+}
+
+#[const_trait] //~ ERROR attribute should be applied
+fn main() {}
diff --git a/tests/ui/traits/const-traits/attr-misuse.stderr b/tests/ui/traits/const-traits/attr-misuse.stderr
new file mode 100644
index 00000000000..998958cedf7
--- /dev/null
+++ b/tests/ui/traits/const-traits/attr-misuse.stderr
@@ -0,0 +1,18 @@
+error: attribute should be applied to a trait
+  --> $DIR/attr-misuse.rs:9:1
+   |
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^
+LL | fn main() {}
+   | ------------ not a trait
+
+error: attribute should be applied to a trait
+  --> $DIR/attr-misuse.rs:5:5
+   |
+LL |     #[const_trait]
+   |     ^^^^^^^^^^^^^^
+LL |     fn foo(self);
+   |     ------------- not a trait
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/const-traits/auxiliary/cross-crate.rs b/tests/ui/traits/const-traits/auxiliary/cross-crate.rs
new file mode 100644
index 00000000000..8f63cd1d521
--- /dev/null
+++ b/tests/ui/traits/const-traits/auxiliary/cross-crate.rs
@@ -0,0 +1,25 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+pub trait MyTrait {
+    fn defaulted_func(&self) {}
+    fn func(self);
+}
+
+pub struct NonConst;
+
+impl MyTrait for NonConst {
+    fn func(self) {
+
+    }
+}
+
+pub struct Const;
+
+impl const MyTrait for Const {
+    fn func(self) {
+
+    }
+}
diff --git a/tests/ui/traits/const-traits/auxiliary/staged-api.rs b/tests/ui/traits/const-traits/auxiliary/staged-api.rs
new file mode 100644
index 00000000000..986165ef91e
--- /dev/null
+++ b/tests/ui/traits/const-traits/auxiliary/staged-api.rs
@@ -0,0 +1,21 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+#![feature(staged_api)]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
+pub trait MyTrait {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn func();
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Unstable;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "unstable", issue = "none")]
+impl const MyTrait for Unstable {
+    fn func() {}
+}
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.rs b/tests/ui/traits/const-traits/call-const-trait-method-fail.rs
new file mode 100644
index 00000000000..878f9a713a0
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.rs
@@ -0,0 +1,31 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+pub trait Plus {
+    fn plus(self, rhs: Self) -> Self;
+}
+
+impl const Plus for i32 {
+    fn plus(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Plus for u32 {
+    fn plus(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+pub const fn add_i32(a: i32, b: i32) -> i32 {
+    a.plus(b) // ok
+}
+
+pub const fn add_u32(a: u32, b: u32) -> u32 {
+    a.plus(b)
+    //~^ ERROR the trait bound `u32: ~const Plus`
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..5d2333d94fe
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr
@@ -0,0 +1,22 @@
+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
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
new file mode 100644
index 00000000000..b854b422b3a
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
@@ -0,0 +1,43 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl)]
+
+struct Int(i32);
+
+impl const std::ops::Add for Int {
+    type Output = Int;
+
+    fn add(self, rhs: Self) -> Self {
+        Int(self.0.plus(rhs.0))
+    }
+}
+
+impl const PartialEq for Int {
+    fn eq(&self, rhs: &Self) -> bool {
+        self.0 == rhs.0
+    }
+    fn ne(&self, other: &Self) -> bool {
+        !self.eq(other)
+    }
+}
+
+#[const_trait]
+pub trait Plus {
+    fn plus(self, rhs: Self) -> Self;
+}
+
+impl const Plus for i32 {
+    fn plus(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+pub const fn add_i32(a: i32, b: i32) -> i32 {
+    a.plus(b)
+}
+
+const ADD_INT: Int = Int(1i32) + Int(2i32);
+
+fn main() {
+    assert!(ADD_INT == Int(3i32));
+}
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
new file mode 100644
index 00000000000..bf455a714a3
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
@@ -0,0 +1,79 @@
+error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
+  --> $DIR/call-const-trait-method-pass.rs:7:12
+   |
+LL | impl const std::ops::Add for Int {
+   |            ^^^^^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
+  --> $DIR/call-const-trait-method-pass.rs:15:12
+   |
+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
+   |
+LL | const ADD_INT: Int = Int(1i32) + Int(2i32);
+   |                      ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error[E0015]: cannot call non-const fn `<i32 as Plus>::plus` in constant functions
+  --> $DIR/call-const-trait-method-pass.rs:11:20
+   |
+LL |         Int(self.0.plus(rhs.0))
+   |                    ^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error[E0015]: cannot call non-const fn `<Int as PartialEq>::eq` in constant functions
+  --> $DIR/call-const-trait-method-pass.rs:20:15
+   |
+LL |         !self.eq(other)
+   |               ^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error[E0015]: cannot call non-const fn `<i32 as Plus>::plus` in constant functions
+  --> $DIR/call-const-trait-method-pass.rs:36:7
+   |
+LL |     a.plus(b)
+   |       ^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0015, E0049.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/call-generic-in-impl.rs b/tests/ui/traits/const-traits/call-generic-in-impl.rs
new file mode 100644
index 00000000000..6b3a4ae1b95
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-in-impl.rs
@@ -0,0 +1,16 @@
+//@ known-bug: #110395
+// FIXME(effects) check-pass
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait MyPartialEq {
+    fn eq(&self, other: &Self) -> bool;
+}
+
+impl<T: ~const PartialEq> const MyPartialEq for T {
+    fn eq(&self, other: &Self) -> bool {
+        PartialEq::eq(self, other)
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-generic-in-impl.stderr b/tests/ui/traits/const-traits/call-generic-in-impl.stderr
new file mode 100644
index 00000000000..5cd274c6c5a
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-in-impl.stderr
@@ -0,0 +1,31 @@
+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 {
+   |                ^^^^^^^^^
+
+error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters
+  --> $DIR/call-generic-in-impl.rs:5:1
+   |
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^ found 1 const parameter
+LL | trait MyPartialEq {
+LL |     fn eq(&self, other: &Self) -> bool;
+   |          - expected 0 const parameters
+
+error[E0015]: cannot call non-const fn `<T as PartialEq>::eq` in constant functions
+  --> $DIR/call-generic-in-impl.rs:12:9
+   |
+LL |         PartialEq::eq(self, other)
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.rs b/tests/ui/traits/const-traits/call-generic-method-chain.rs
new file mode 100644
index 00000000000..9df694a02f5
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-chain.rs
@@ -0,0 +1,29 @@
+//! Basic test for calling methods on generic type parameters in `const fn`.
+
+//@ known-bug: #110395
+// FIXME(effects) check-pass
+
+#![feature(const_trait_impl, effects)]
+
+struct S;
+
+impl const PartialEq for S {
+    fn eq(&self, _: &S) -> bool {
+        true
+    }
+    fn ne(&self, other: &S) -> bool {
+        !self.eq(other)
+    }
+}
+
+const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
+    *t == *t
+}
+
+const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
+    equals_self(t)
+}
+
+pub const EQ: bool = equals_self_wrapper(&S);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.stderr b/tests/ui/traits/const-traits/call-generic-method-chain.stderr
new file mode 100644
index 00000000000..57d57dfd5b9
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-chain.stderr
@@ -0,0 +1,37 @@
+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
+   |
+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
+   |
+LL | impl const PartialEq for S {
+   |            ^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-chain.rs:19: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:23:40
+   |
+LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
+   |                                        ^^^^^^^^^
+
+error: aborting due to 4 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
new file mode 100644
index 00000000000..f46a34911f1
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs
@@ -0,0 +1,32 @@
+//@ known-bug: #110395
+// FIXME(effects) check-pass
+
+#![feature(const_trait_impl, effects)]
+
+struct S;
+
+impl const PartialEq for S {
+    fn eq(&self, _: &S) -> bool {
+        true
+    }
+    fn ne(&self, other: &S) -> bool {
+        !self.eq(other)
+    }
+}
+
+// This duplicate bound should not result in ambiguities. It should be equivalent to a single ~const
+// bound.
+const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
+    *t == *t
+}
+
+trait A: PartialEq {}
+impl<T: PartialEq> A for T {}
+
+const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
+    *t == *t
+}
+
+pub const EQ: bool = equals_self(&S) && equals_self2(&S);
+
+fn main() {}
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
new file mode 100644
index 00000000000..0088ed2eb13
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr
@@ -0,0 +1,37 @@
+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
+   |
+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
+   |
+LL | impl const PartialEq for S {
+   |            ^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-dup-bound.rs:19: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:26:37
+   |
+LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
+   |                                     ^^^^^^^^^
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/call-generic-method-fail.rs b/tests/ui/traits/const-traits/call-generic-method-fail.rs
new file mode 100644
index 00000000000..86e0eae61c9
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-fail.rs
@@ -0,0 +1,12 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
+    *t == *t
+    // FIXME(effects) ~^ ERROR mismatched types
+    // FIXME(effects): diagnostic
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs b/tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs
new file mode 100644
index 00000000000..9dbc2b95626
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst-bound.rs
@@ -0,0 +1,17 @@
+//@ check-pass
+
+struct S;
+
+impl PartialEq for S {
+    fn eq(&self, _: &S) -> bool {
+        true
+    }
+}
+
+const fn equals_self<T: PartialEq>(t: &T) -> bool {
+    true
+}
+
+pub const EQ: bool = equals_self(&S);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.rs b/tests/ui/traits/const-traits/call-generic-method-nonconst.rs
new file mode 100644
index 00000000000..f9e79d41752
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.rs
@@ -0,0 +1,28 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+struct S;
+
+#[const_trait]
+trait Foo {
+    fn eq(&self, _: &Self) -> bool;
+}
+
+impl Foo for S {
+    fn eq(&self, _: &S) -> bool {
+        true
+    }
+}
+
+const fn equals_self<T: ~const Foo>(t: &T) -> bool {
+    true
+}
+
+// Calling `equals_self` with something that has a non-const impl should throw an error, despite
+// it not using the impl.
+
+pub const EQ: bool = equals_self(&S);
+//~^ ERROR: the trait bound `S: const Foo` is not satisfied
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
new file mode 100644
index 00000000000..68c9fc40010
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `S: const Foo` is not satisfied
+  --> $DIR/call-generic-method-nonconst.rs:25:34
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.rs b/tests/ui/traits/const-traits/call-generic-method-pass.rs
new file mode 100644
index 00000000000..413685d8b34
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-pass.rs
@@ -0,0 +1,25 @@
+//! Basic test for calling methods on generic type parameters in `const fn`.
+
+//@ known-bug: #110395
+// FIXME(effects) check-pass
+
+#![feature(const_trait_impl, effects)]
+
+struct S;
+
+impl const PartialEq for S {
+    fn eq(&self, _: &S) -> bool {
+        true
+    }
+    fn ne(&self, other: &S) -> bool {
+        !self.eq(other)
+    }
+}
+
+const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
+    *t == *t
+}
+
+pub const EQ: bool = equals_self(&S);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.stderr b/tests/ui/traits/const-traits/call-generic-method-pass.stderr
new file mode 100644
index 00000000000..4a6100c3c1a
--- /dev/null
+++ b/tests/ui/traits/const-traits/call-generic-method-pass.stderr
@@ -0,0 +1,31 @@
+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
+   |
+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
+   |
+LL | impl const PartialEq for S {
+   |            ^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/call-generic-method-pass.rs:19:32
+   |
+LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
+   |                                ^^^^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs
new file mode 100644
index 00000000000..af2f7caf88c
--- /dev/null
+++ b/tests/ui/traits/const-traits/call.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![feature(const_closures, const_trait_impl, effects)]
+#![allow(incomplete_features)]
+
+pub const _: () = {
+    assert!((const || true)());
+};
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-and-non-const-impl.rs b/tests/ui/traits/const-traits/const-and-non-const-impl.rs
new file mode 100644
index 00000000000..6b96fcf0ae3
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.rs
@@ -0,0 +1,31 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl)]
+
+pub struct Int(i32);
+
+impl const std::ops::Add for i32 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl std::ops::Add for Int {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        Int(self.0 + rhs.0)
+    }
+}
+
+impl const std::ops::Add for Int {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        Int(self.0 + rhs.0)
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
new file mode 100644
index 00000000000..cf7af41cd4e
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
@@ -0,0 +1,44 @@
+error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
+  --> $DIR/const-and-non-const-impl.rs:7:12
+   |
+LL | impl const std::ops::Add for i32 {
+   |            ^^^^^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
+  --> $DIR/const-and-non-const-impl.rs:23:12
+   |
+LL | impl const std::ops::Add for Int {
+   |            ^^^^^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error[E0119]: conflicting implementations of trait `Add` for type `Int`
+  --> $DIR/const-and-non-const-impl.rs:23:1
+   |
+LL | impl std::ops::Add for Int {
+   | -------------------------- first implementation here
+...
+LL | impl const std::ops::Add for Int {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int`
+
+error[E0117]: only traits defined in the current crate can be implemented for primitive types
+  --> $DIR/const-and-non-const-impl.rs:7:1
+   |
+LL | impl const std::ops::Add for i32 {
+   | ^^^^^^^^^^^-------------^^^^^---
+   |            |                 |
+   |            |                 `i32` is not defined in the current crate
+   |            `i32` is not defined in the current crate
+   |
+   = note: impl doesn't have any local type before any uncovered type parameters
+   = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
+   = note: define and implement a trait or new type instead
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0117, E0119.
+For more information about an error, try `rustc --explain E0117`.
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
new file mode 100644
index 00000000000..099cf0b00d3
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs
@@ -0,0 +1,29 @@
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait MyTrait {
+    fn do_something(&self);
+}
+
+trait OtherTrait {
+    fn do_something_else() where Self: ~const MyTrait;
+    //~^ ERROR `~const` is not allowed here
+}
+
+struct MyStruct<T>(T);
+
+impl const MyTrait for u32 {
+    fn do_something(&self) {}
+}
+
+impl<T> MyStruct<T> {
+    pub fn foo(&self) where T: ~const MyTrait {
+        //~^ ERROR `~const` is not allowed here
+        self.0.do_something();
+    }
+}
+
+fn main() {
+    MyStruct(0u32).foo();
+}
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
new file mode 100644
index 00000000000..b5d9b1fff8a
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr
@@ -0,0 +1,31 @@
+error: `~const` is not allowed here
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:10: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
+   |
+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
+   |
+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
+   |
+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
+
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
new file mode 100644
index 00000000000..db446f8bc2e
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs
@@ -0,0 +1,12 @@
+// Regression test for issue #117244.
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+trait NonConst {}
+
+const fn perform<T: ~const NonConst>() {}
+//~^ 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
+
+fn main() {}
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
new file mode 100644
index 00000000000..e1a85fc5414
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr
@@ -0,0 +1,28 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/const-bounds-non-const-trait.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: 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-bounds-non-const-trait.rs:6:28
+   |
+LL | const fn perform<T: ~const NonConst>() {}
+   |                            ^^^^^^^^
+
+error: `const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-bounds-non-const-trait.rs:9:21
+   |
+LL | fn operate<T: const NonConst>() {}
+   |                     ^^^^^^^^
+
+error: aborting due to 3 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
new file mode 100644
index 00000000000..a1710e65252
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs
@@ -0,0 +1,16 @@
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+struct S;
+#[const_trait]
+trait T {
+    fn foo();
+}
+
+fn non_const() {}
+
+impl const T for S {
+    fn foo() { non_const() }
+    //~^ ERROR cannot call non-const fn
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..49cd1725c8c
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr
@@ -0,0 +1,25 @@
+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
+   |
+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
+   |
+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
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-closure-parse-not-item.rs b/tests/ui/traits/const-traits/const-closure-parse-not-item.rs
new file mode 100644
index 00000000000..b1b0e68b90d
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closure-parse-not-item.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #110395
+// FIXME check-pass
+
+#![feature(const_trait_impl, const_closures)]
+#![allow(incomplete_features)]
+
+const fn test() -> impl ~const Fn() {
+    const move || {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
new file mode 100644
index 00000000000..12cc79f5961
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr
@@ -0,0 +1,16 @@
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closure-parse-not-item.rs:7:32
+   |
+LL | const fn test() -> impl ~const Fn() {
+   |                                ^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closure-parse-not-item.rs:7:32
+   |
+LL | const fn test() -> impl ~const Fn() {
+   |                                ^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs b/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs
new file mode 100644
index 00000000000..8c6286426d3
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs
@@ -0,0 +1,20 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Tr {
+    fn a(self) -> i32;
+}
+
+impl Tr for () {
+    fn a(self) -> i32 { 42 }
+}
+
+const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
+    x(())
+}
+
+const _: () = assert!(need_const_closure(Tr::a) == 42);
+
+fn main() {}
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
new file mode 100644
index 00000000000..507ceaae2ea
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr
@@ -0,0 +1,35 @@
+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[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closure-trait-method-fail.rs:15:5
+   |
+LL |     x(())
+   |     ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: consider further restricting this bound
+   |
+LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const FnOnce(())>(x: T) -> i32 {
+   |                                                         +++++++++++++++++++
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.rs b/tests/ui/traits/const-traits/const-closure-trait-method.rs
new file mode 100644
index 00000000000..ebee4daefbe
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closure-trait-method.rs
@@ -0,0 +1,20 @@
+//@ known-bug: #110395
+// FIXME check-pass
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Tr {
+    fn a(self) -> i32;
+}
+
+impl const Tr for () {
+    fn a(self) -> i32 { 42 }
+}
+
+const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
+    x(())
+}
+
+const _: () = assert!(need_const_closure(Tr::a) == 42);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
new file mode 100644
index 00000000000..2a54cd5d7f6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closure-trait-method.stderr
@@ -0,0 +1,35 @@
+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[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closure-trait-method.rs:15:5
+   |
+LL |     x(())
+   |     ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: consider further restricting this bound
+   |
+LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const FnOnce(())>(x: T) -> i32 {
+   |                                                         +++++++++++++++++++
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/const-closures.rs b/tests/ui/traits/const-traits/const-closures.rs
new file mode 100644
index 00000000000..98f8d039cd6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closures.rs
@@ -0,0 +1,31 @@
+//@ known-bug: #110395
+// FIXME check-pass
+
+#![feature(const_trait_impl)]
+
+const fn answer_p1<F>(f: &F) -> u8
+    where
+        F: ~const FnOnce() -> u8,
+        F: ~const FnMut() -> u8,
+        F: ~const Fn() -> u8,
+{
+    f() * 7
+}
+
+const fn three() -> u8 {
+    3
+}
+
+const fn answer_p2() -> u8 {
+    answer_p1(&three)
+}
+
+const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
+    f() + f()
+}
+
+const ANSWER: u8 = answer(&answer_p2);
+
+fn main() {
+    assert_eq!(ANSWER, 42)
+}
diff --git a/tests/ui/traits/const-traits/const-closures.stderr b/tests/ui/traits/const-traits/const-closures.stderr
new file mode 100644
index 00000000000..a0f05325389
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-closures.stderr
@@ -0,0 +1,75 @@
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:8:19
+   |
+LL |         F: ~const FnOnce() -> u8,
+   |                   ^^^^^^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:9:19
+   |
+LL |         F: ~const FnMut() -> u8,
+   |                   ^^^^^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-closures.rs:10:19
+   |
+LL |         F: ~const Fn() -> 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 {
+   |                           ^^^^^^^^^^
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closures.rs:24:5
+   |
+LL |     f() + f()
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: consider further restricting this bound
+   |
+LL | const fn answer<F: ~const Fn() -> u8 + ~const Fn()>(f: &F) -> u8 {
+   |                                      +++++++++++++
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closures.rs:24:11
+   |
+LL |     f() + f()
+   |           ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: consider further restricting this bound
+   |
+LL | const fn answer<F: ~const Fn() -> u8 + ~const Fn()>(f: &F) -> u8 {
+   |                                      +++++++++++++
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closures.rs:12:5
+   |
+LL |     f() * 7
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: consider further restricting this bound
+   |
+LL |         F: ~const FnOnce() -> u8 + ~const Fn(),
+   |                                  +++++++++++++
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.rs b/tests/ui/traits/const-traits/const-default-method-bodies.rs
new file mode 100644
index 00000000000..a0333153f85
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-default-method-bodies.rs
@@ -0,0 +1,31 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait ConstDefaultFn: Sized {
+    fn b(self);
+
+    fn a(self) {
+        self.b();
+    }
+}
+
+struct NonConstImpl;
+struct ConstImpl;
+
+impl ConstDefaultFn for NonConstImpl {
+    fn b(self) {}
+}
+
+impl const ConstDefaultFn for ConstImpl {
+    fn b(self) {}
+}
+
+const fn test() {
+    NonConstImpl.a();
+    //~^ ERROR the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
+    ConstImpl.a();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr
new file mode 100644
index 00000000000..0809d9c1e1d
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-default-method-bodies.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
+  --> $DIR/const-default-method-bodies.rs:26:18
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-drop-bound.rs b/tests/ui/traits/const-traits/const-drop-bound.rs
new file mode 100644
index 00000000000..b0790f86ef5
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-bound.rs
@@ -0,0 +1,26 @@
+//@ known-bug: #110395
+// FIXME check-pass
+
+#![feature(const_trait_impl)]
+#![feature(const_precise_live_drops)]
+
+use std::marker::Destruct;
+
+const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
+    match res {
+        Ok(t) => Some(t),
+        Err(_e) => None,
+    }
+}
+
+pub struct Foo<T>(T);
+
+const fn baz<T, E>(res: Result<Foo<T>, Foo<E>>) -> Option<Foo<T>>
+where
+    T: ~const Destruct,
+    E: ~const Destruct,
+{
+    foo(res)
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr
new file mode 100644
index 00000000000..be197006f02
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-bound.stderr
@@ -0,0 +1,27 @@
+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 {
+   |                                                                    ^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-bound.rs:20:15
+   |
+LL |     T: ~const Destruct,
+   |               ^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-bound.rs:21:15
+   |
+LL |     E: ~const Destruct,
+   |               ^^^^^^^^
+
+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
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
new file mode 100644
index 00000000000..7529af9293d
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
@@ -0,0 +1,26 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail-2.rs:23:25
+   |
+LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
+   |                         ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail-2.rs:29:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail-2.rs:39:25
+   |
+LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
+   |                         ^^^^
+   |
+   = 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
+
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.rs b/tests/ui/traits/const-traits/const-drop-fail-2.rs
new file mode 100644
index 00000000000..7b57e0405af
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.rs
@@ -0,0 +1,45 @@
+//@ known-bug: #110395
+#![feature(const_trait_impl)]
+// #![cfg_attr(precise, feature(const_precise_live_drops))]
+
+use std::marker::{Destruct, PhantomData};
+
+struct NonTrivialDrop;
+
+impl Drop for NonTrivialDrop {
+    fn drop(&mut self) {
+        println!("Non trivial drop");
+    }
+}
+
+#[const_trait]
+trait A { fn a() { } }
+
+impl A for NonTrivialDrop {}
+
+const fn check<T: ~const Destruct>(_: T) {}
+
+
+/* FIXME(effects)
+struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+
+impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
+    fn drop(&mut self) {
+        T::a();
+    }
+}
+
+const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
+    ConstDropImplWithBounds(PhantomData)
+);
+*/
+
+struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
+
+impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
+    fn drop(&mut self) {
+        T::a();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
new file mode 100644
index 00000000000..faf24c6d911
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
@@ -0,0 +1,39 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail-2.rs:39:25
+   |
+LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
+   |                         ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail-2.rs:20:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/const-drop-fail-2.rs:20:36
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                                    ^      - value is dropped here
+   |                                    |
+   |                                    the destructor for this type cannot be evaluated in constant functions
+
+error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
+  --> $DIR/const-drop-fail-2.rs:41:9
+   |
+LL |         T::a();
+   |         ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 4 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-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
new file mode 100644
index 00000000000..7529af9293d
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
@@ -0,0 +1,26 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail-2.rs:23:25
+   |
+LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
+   |                         ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail-2.rs:29:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail-2.rs:39:25
+   |
+LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
+   |                         ^^^^
+   |
+   = 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
+
diff --git a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
new file mode 100644
index 00000000000..3d400bf0158
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
@@ -0,0 +1,77 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail.rs:19:12
+   |
+LL | impl const Drop for ConstImplWithDropGlue {
+   |            ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail.rs:23:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/const-drop-fail.rs:23:36
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                                    ^ the destructor for this type cannot be evaluated in constant functions
+
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+   = note: calling non-const function `<NonTrivialDrop as Drop>::drop`
+   |
+note: inside `std::ptr::drop_in_place::<NonTrivialDrop> - shim(Some(NonTrivialDrop))`
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `check::<NonTrivialDrop>`
+  --> $DIR/const-drop-fail.rs:23:43
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                                           ^
+note: inside `_`
+  --> $DIR/const-drop-fail.rs:27:23
+   |
+LL |           const _: () = check($exp);
+   |                         ^^^^^^^^^^^
+...
+LL | / check_all! {
+LL | |     NonTrivialDrop,
+LL | |     ConstImplWithDropGlue(NonTrivialDrop),
+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[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+   = note: calling non-const function `<NonTrivialDrop as Drop>::drop`
+   |
+note: inside `std::ptr::drop_in_place::<NonTrivialDrop> - shim(Some(NonTrivialDrop))`
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `std::ptr::drop_in_place::<ConstImplWithDropGlue> - shim(Some(ConstImplWithDropGlue))`
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `check::<ConstImplWithDropGlue>`
+  --> $DIR/const-drop-fail.rs:23:43
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                                           ^
+note: inside `_`
+  --> $DIR/const-drop-fail.rs:27:23
+   |
+LL |           const _: () = check($exp);
+   |                         ^^^^^^^^^^^
+...
+LL | / check_all! {
+LL | |     NonTrivialDrop,
+LL | |     ConstImplWithDropGlue(NonTrivialDrop),
+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
+
+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.rs b/tests/ui/traits/const-traits/const-drop-fail.rs
new file mode 100644
index 00000000000..5a98c32e838
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail.rs
@@ -0,0 +1,36 @@
+//@ known-bug: #110395
+
+//@ revisions: stock precise
+#![feature(const_trait_impl)]
+#![cfg_attr(precise, feature(const_precise_live_drops))]
+
+use std::marker::{Destruct, PhantomData};
+
+struct NonTrivialDrop;
+
+impl Drop for NonTrivialDrop {
+    fn drop(&mut self) {
+        println!("Non trivial drop");
+    }
+}
+
+struct ConstImplWithDropGlue(NonTrivialDrop);
+
+impl const Drop for ConstImplWithDropGlue {
+    fn drop(&mut self) {}
+}
+
+const fn check<T: ~const Destruct>(_: T) {}
+
+macro_rules! check_all {
+    ($($exp:expr),*$(,)?) => {$(
+        const _: () = check($exp);
+    )*};
+}
+
+check_all! {
+    NonTrivialDrop,
+    ConstImplWithDropGlue(NonTrivialDrop),
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
new file mode 100644
index 00000000000..fd0f6d02684
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
@@ -0,0 +1,26 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop-fail.rs:19:12
+   |
+LL | impl const Drop for ConstImplWithDropGlue {
+   |            ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop-fail.rs:23:26
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                          ^^^^^^^^
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/const-drop-fail.rs:23:36
+   |
+LL | const fn check<T: ~const Destruct>(_: T) {}
+   |                                    ^      - value is dropped here
+   |                                    |
+   |                                    the destructor for this type cannot be evaluated in constant functions
+
+error: aborting due to 3 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
new file mode 100644
index 00000000000..dd3ea5d241d
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop.precise.stderr
@@ -0,0 +1,84 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:12:16
+   |
+LL | impl<'a> const Drop for S<'a> {
+   |                ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:46:16
+   |
+LL |     impl const Drop for ConstDrop {
+   |                ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:67:37
+   |
+LL |     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
+   |                                     ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:75:30
+   |
+LL |     impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
+   |                              ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop.rs:18:22
+   |
+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
+   |
+LL |     #[const_trait]
+   |     ^^^^^^^^^^^^^^ found 1 const parameter
+LL |     pub trait SomeTrait {
+LL |         fn foo();
+   |               - expected 0 const parameters
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/const-drop.rs:18:32
+   |
+LL | const fn a<T: ~const Destruct>(_: T) {}
+   |                                ^ the destructor for this type cannot be evaluated in constant functions
+
+error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
+  --> $DIR/const-drop.rs:69:13
+   |
+LL |             T::foo();
+   |             ^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0015, E0049, E0493.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs
new file mode 100644
index 00000000000..5bd81fb3ab6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop.rs
@@ -0,0 +1,115 @@
+// FIXME run-pass
+//@ known-bug: #110395
+//@ revisions: stock precise
+#![feature(const_trait_impl)]
+#![feature(never_type)]
+#![cfg_attr(precise, feature(const_precise_live_drops))]
+
+use std::marker::Destruct;
+
+struct S<'a>(&'a mut u8);
+
+impl<'a> const Drop for S<'a> {
+    fn drop(&mut self) {
+        *self.0 += 1;
+    }
+}
+
+const fn a<T: ~const Destruct>(_: T) {}
+//FIXME ~^ ERROR destructor of
+
+const fn b() -> u8 {
+    let mut c = 0;
+    let _ = S(&mut c);
+    //FIXME ~^ ERROR destructor of
+    a(S(&mut c));
+    c
+}
+
+const C: u8 = b();
+
+macro_rules! implements_const_drop {
+    ($($exp:expr),*$(,)?) => {
+        $(
+            const _: () = a($exp);
+        )*
+    }
+}
+
+#[allow(dead_code)]
+mod t {
+    pub struct Foo;
+    pub enum Bar { A }
+    pub fn foo() {}
+    pub struct ConstDrop;
+
+    impl const Drop for ConstDrop {
+        fn drop(&mut self) {}
+    }
+
+    pub struct HasConstDrop(pub ConstDrop);
+    pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize);
+
+    #[const_trait]
+    pub trait SomeTrait {
+        fn foo();
+    }
+    impl const SomeTrait for () {
+        fn foo() {}
+    }
+    // non-const impl
+    impl SomeTrait for i32 {
+        fn foo() {}
+    }
+
+    pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
+
+    impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
+        fn drop(&mut self) {
+            T::foo();
+        }
+    }
+
+    pub struct ConstDropWithNonconstBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
+
+    impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
+        fn drop(&mut self) {
+            // Note: we DON'T use the `T: SomeTrait` bound
+        }
+    }
+}
+
+use t::*;
+
+implements_const_drop! {
+    1u8,
+    2,
+    3.0,
+    Foo,
+    Bar::A,
+    foo,
+    ConstDrop,
+    HasConstDrop(ConstDrop),
+    TrivialFields(1, 2, 3, 4),
+    &1,
+    &1 as *const i32,
+    ConstDropWithBound::<()>,
+    ConstDropWithNonconstBound::<i32>,
+    Result::<i32, !>::Ok(1),
+}
+
+fn main() {
+    struct HasDropGlue(#[allow(dead_code)] Box<u8>);
+    struct HasDropImpl;
+    impl Drop for HasDropImpl {
+        fn drop(&mut self) {
+            println!("not trivial drop");
+        }
+    }
+
+    // These types should pass because ~const in a non-const context should have no effect.
+    a(HasDropGlue(Box::new(0)));
+    a(HasDropImpl);
+
+    assert_eq!(C, 2);
+}
diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr
new file mode 100644
index 00000000000..aa59e1c8dc4
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-drop.stock.stderr
@@ -0,0 +1,86 @@
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:12:16
+   |
+LL | impl<'a> const Drop for S<'a> {
+   |                ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:46:16
+   |
+LL |     impl const Drop for ConstDrop {
+   |                ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:67:37
+   |
+LL |     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
+   |                                     ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
+  --> $DIR/const-drop.rs:75:30
+   |
+LL |     impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
+   |                              ^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-drop.rs:18:22
+   |
+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
+   |
+LL |     #[const_trait]
+   |     ^^^^^^^^^^^^^^ found 1 const parameter
+LL |     pub trait SomeTrait {
+LL |         fn foo();
+   |               - expected 0 const parameters
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/const-drop.rs:18:32
+   |
+LL | const fn a<T: ~const Destruct>(_: T) {}
+   |                                ^      - value is dropped here
+   |                                |
+   |                                the destructor for this type cannot be evaluated in constant functions
+
+error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
+  --> $DIR/const-drop.rs:69:13
+   |
+LL |             T::foo();
+   |             ^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0015, E0049, 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
new file mode 100644
index 00000000000..b3087349e4d
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs
@@ -0,0 +1,136 @@
+//@ known-bug: #110395
+// FIXME(effects) check-pass
+//@ compile-flags: -Znext-solver
+
+#![crate_type = "lib"]
+#![allow(internal_features, incomplete_features)]
+#![no_std]
+#![no_core]
+#![feature(
+    auto_traits,
+    const_trait_impl,
+    effects,
+    lang_items,
+    no_core,
+    staged_api,
+    unboxed_closures,
+    rustc_attrs,
+    marker_trait_attr,
+)]
+#![stable(feature = "minicore", since = "1.0.0")]
+
+fn test() {
+    fn is_const_fn<F>(_: F)
+    where
+        F: const FnOnce<()>,
+    {
+    }
+
+    const fn foo() {}
+
+    is_const_fn(foo);
+}
+
+/// ---------------------------------------------------------------------- ///
+/// Const fn trait definitions
+
+#[const_trait]
+#[lang = "fn"]
+#[rustc_paren_sugar]
+trait Fn<Args: Tuple>: ~const FnMut<Args> {
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[const_trait]
+#[lang = "fn_mut"]
+#[rustc_paren_sugar]
+trait FnMut<Args: Tuple>: ~const FnOnce<Args> {
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[const_trait]
+#[lang = "fn_once"]
+#[rustc_paren_sugar]
+trait FnOnce<Args: Tuple> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+/// ---------------------------------------------------------------------- ///
+/// All this other stuff needed for core. Unrelated to test.
+
+#[lang = "destruct"]
+#[const_trait]
+trait Destruct {}
+
+#[lang = "freeze"]
+unsafe auto trait Freeze {}
+
+#[lang = "drop"]
+#[const_trait]
+trait Drop {
+    fn drop(&mut self);
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "tuple_trait"]
+trait Tuple {}
+
+#[lang = "receiver"]
+trait Receiver {}
+
+impl<T: ?Sized> Receiver for &T {}
+
+impl<T: ?Sized> Receiver 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
new file mode 100644
index 00000000000..9eda9d98ec5
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr
@@ -0,0 +1,20 @@
+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-norecover.rs b/tests/ui/traits/const-traits/const-impl-norecover.rs
new file mode 100644
index 00000000000..bed4e9fd1e6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-norecover.rs
@@ -0,0 +1,12 @@
+#![feature(const_trait_impl)]
+
+struct Foo;
+
+const impl Foo { //~ ERROR: expected identifier, found keyword
+    fn bar() {}
+}
+
+fn main() {
+     // shouldn't error here because we shouldn't have been able to recover above
+     Foo::bar();
+}
diff --git a/tests/ui/traits/const-traits/const-impl-norecover.stderr b/tests/ui/traits/const-traits/const-impl-norecover.stderr
new file mode 100644
index 00000000000..efa72463c5e
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-norecover.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found keyword `impl`
+  --> $DIR/const-impl-norecover.rs:5:7
+   |
+LL | const impl Foo {
+   |       ^^^^ expected identifier, found keyword
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/traits/const-traits/const-impl-recovery.rs b/tests/ui/traits/const-traits/const-impl-recovery.rs
new file mode 100644
index 00000000000..837124db04e
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-recovery.rs
@@ -0,0 +1,17 @@
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Foo {}
+
+const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword
+
+#[const_trait]
+trait Bar {}
+
+const impl<T: Foo> Bar for T {} //~ ERROR: expected identifier, found keyword
+
+const fn still_implements<T: Bar>() {}
+
+const _: () = still_implements::<i32>();
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-impl-recovery.stderr b/tests/ui/traits/const-traits/const-impl-recovery.stderr
new file mode 100644
index 00000000000..7217fc85543
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-recovery.stderr
@@ -0,0 +1,26 @@
+error: expected identifier, found keyword `impl`
+  --> $DIR/const-impl-recovery.rs:6:7
+   |
+LL | const impl Foo for i32 {}
+   |       ^^^^ expected identifier, found keyword
+   |
+help: you might have meant to write a const trait impl
+   |
+LL - const impl Foo for i32 {}
+LL + impl const Foo for i32 {}
+   |
+
+error: expected identifier, found keyword `impl`
+  --> $DIR/const-impl-recovery.rs:11:7
+   |
+LL | const impl<T: Foo> Bar for T {}
+   |       ^^^^ expected identifier, found keyword
+   |
+help: you might have meant to write a const trait impl
+   |
+LL - const impl<T: Foo> Bar for T {}
+LL + impl<T: Foo> const Bar for T {}
+   |
+
+error: aborting due to 2 previous errors
+
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
new file mode 100644
index 00000000000..bd6f476f879
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl, effects)]
+
+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]`
+
+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
new file mode 100644
index 00000000000..2a030369093
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr
@@ -0,0 +1,28 @@
+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
+   |
+LL | pub trait A {}
+   | - help: mark `A` as const: `#[const_trait]`
+...
+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
+
diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs
new file mode 100644
index 00000000000..51dfe29b829
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-trait.rs
@@ -0,0 +1,56 @@
+//@ known-bug: #110395
+// Broken until we have `&T: const Deref` impl in stdlib
+
+#![allow(incomplete_features)]
+#![feature(
+    const_trait_impl,
+    effects,
+    const_cmp,
+)]
+
+use std::marker::Destruct;
+
+const fn cmp(a: &impl ~const PartialEq) -> bool {
+    a == a
+}
+
+const fn wrap(x: impl ~const PartialEq + ~const Destruct)
+    -> impl ~const PartialEq + ~const Destruct
+{
+    x
+}
+
+#[const_trait]
+trait Foo {
+    fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+}
+
+impl const Foo for () {
+    fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
+        123
+    }
+}
+
+const _: () = {
+    assert!(cmp(&0xDEADBEEFu32));
+    assert!(cmp(&()));
+    assert!(wrap(123) == wrap(123));
+    assert!(wrap(123) != wrap(456));
+    let x = <() as Foo>::huh();
+    assert!(x == x);
+};
+
+#[const_trait]
+trait T {}
+struct S;
+impl const T for S {}
+
+const fn rpit() -> impl ~const T { S }
+
+const fn apit(_: impl ~const T + ~const Destruct) {}
+
+const fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
+
+const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr
new file mode 100644
index 00000000000..1040af7541c
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-impl-trait.stderr
@@ -0,0 +1,249 @@
+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-trait-bounds-trait-objects.rs b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
new file mode 100644
index 00000000000..691bce19dc2
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
@@ -0,0 +1,18 @@
+#![feature(const_trait_impl)]
+// FIXME(effects) add effects
+//@ edition: 2021
+
+#[const_trait]
+trait Trait {}
+
+fn main() {
+    let _: &dyn const Trait; //~ ERROR const trait bounds are not allowed in trait object types
+    let _: &dyn ~const Trait; //~ ERROR `~const` is not allowed here
+}
+
+// Regression test for issue #119525.
+trait NonConst {}
+const fn handle(_: &dyn const NonConst) {}
+//~^ ERROR const trait bounds are not allowed in trait object types
+const fn take(_: &dyn ~const NonConst) {}
+//~^ ERROR `~const` is not allowed here
diff --git a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
new file mode 100644
index 00000000000..bd29b4b860b
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
@@ -0,0 +1,30 @@
+error: const trait bounds are not allowed in trait object types
+  --> $DIR/const-trait-bounds-trait-objects.rs:9:17
+   |
+LL |     let _: &dyn const Trait;
+   |                 ^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/const-trait-bounds-trait-objects.rs:10:17
+   |
+LL |     let _: &dyn ~const Trait;
+   |                 ^^^^^^
+   |
+   = note: trait objects cannot have `~const` trait bounds
+
+error: const trait bounds are not allowed in trait object types
+  --> $DIR/const-trait-bounds-trait-objects.rs:15:25
+   |
+LL | const fn handle(_: &dyn const NonConst) {}
+   |                         ^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/const-trait-bounds-trait-objects.rs:17:23
+   |
+LL | const fn take(_: &dyn ~const NonConst) {}
+   |                       ^^^^^^
+   |
+   = note: trait objects cannot have `~const` trait bounds
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/traits/const-traits/const-trait-bounds.rs b/tests/ui/traits/const-traits/const-trait-bounds.rs
new file mode 100644
index 00000000000..3b4ba6a998f
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-bounds.rs
@@ -0,0 +1,32 @@
+//@ known-bug: #110395
+//@ compile-flags: -Znext-solver
+// FIXME(effects): check-pass
+#![feature(const_trait_impl, effects, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn main() {
+    let _ = process::<()>([()]);
+    let _ = Struct::<(), 4> { field: [1, 0] };
+}
+
+fn process<T: const Trait>(input: [(); T::make(2)]) -> [(); T::make(2)] {
+    input
+}
+
+struct Struct<T: const Trait, const P: usize>
+where
+    [u32; T::make(P)]:,
+{
+    field: [u32; T::make(P)],
+}
+
+#[const_trait]
+trait Trait {
+    fn make(input: usize) -> usize;
+}
+
+impl const Trait for () {
+    fn make(input: usize) -> usize {
+        input / 2
+    }
+}
diff --git a/tests/ui/traits/const-traits/const-trait-bounds.stderr b/tests/ui/traits/const-traits/const-trait-bounds.stderr
new file mode 100644
index 00000000000..698b1b5b578
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-bounds.stderr
@@ -0,0 +1,29 @@
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/const-trait-bounds.rs:4:39
+   |
+LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
+   |                                       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
+error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#0}`
+  --> $DIR/const-trait-bounds.rs:12:35
+   |
+LL | fn process<T: const Trait>(input: [(); T::make(2)]) -> [(); T::make(2)] {
+   |                                   ^^^^^^^^^^^^^^^^ cannot normalize `process<T>::{constant#0}`
+
+error[E0284]: type annotations needed: cannot normalize `Struct<T, P>::field::{constant#0}`
+  --> $DIR/const-trait-bounds.rs:20:12
+   |
+LL |     field: [u32; T::make(P)],
+   |            ^^^^^^^^^^^^^^^^^ cannot normalize `Struct<T, P>::field::{constant#0}`
+
+error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#1}`
+  --> $DIR/const-trait-bounds.rs:13:5
+   |
+LL |     input
+   |     ^^^^^ cannot normalize `process<T>::{constant#1}`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
new file mode 100644
index 00000000000..a772d69c9e2
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
@@ -0,0 +1,5 @@
+#[derive_const(Default)] //~ ERROR use of unstable library feature
+//~^ ERROR const `impl` for trait `Default` which is not marked with `#[const_trait]`
+pub struct S;
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
new file mode 100644
index 00000000000..3ccae5a83e6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
@@ -0,0 +1,22 @@
+error[E0658]: use of unstable library feature 'derive_const'
+  --> $DIR/derive-const-gate.rs:1:3
+   |
+LL | #[derive_const(Default)]
+   |   ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(derive_const)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-gate.rs:1:16
+   |
+LL | #[derive_const(Default)]
+   |                ^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
new file mode 100644
index 00000000000..5896091f8c4
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #110395
+#![feature(derive_const, effects)]
+
+pub struct A;
+
+impl Default for A {
+    fn default() -> A { A }
+}
+
+#[derive_const(Default)]
+pub struct S(A);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
new file mode 100644
index 00000000000..777b3313da6
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
@@ -0,0 +1,26 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/derive-const-non-const-type.rs:2:26
+   |
+LL | #![feature(derive_const, 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 `Default` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-non-const-type.rs:10:16
+   |
+LL | #[derive_const(Default)]
+   |                ^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
new file mode 100644
index 00000000000..cb649b1ec79
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
@@ -0,0 +1,20 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
+
+pub struct A;
+
+impl const Default for A {
+    fn default() -> A { A }
+}
+
+impl const PartialEq for A {
+    fn eq(&self, _: &A) -> bool { true }
+}
+
+#[derive_const(Default, PartialEq)]
+pub struct S((), A);
+
+const _: () = assert!(S((), A) == S::default());
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
new file mode 100644
index 00000000000..ad727fc36cd
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
@@ -0,0 +1,90 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/derive-const-use.rs:3:76
+   |
+LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
+   |                                                                            ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0635]: unknown feature `const_cmp`
+  --> $DIR/derive-const-use.rs:3:30
+   |
+LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
+   |                              ^^^^^^^^^
+
+error[E0635]: unknown feature `const_default_impls`
+  --> $DIR/derive-const-use.rs:3:41
+   |
+LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
+   |                                         ^^^^^^^^^^^^^^^^^^^
+
+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 `Default` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-use.rs:7:12
+   |
+LL | impl const Default for A {
+   |            ^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-use.rs:15:16
+   |
+LL | #[derive_const(Default, PartialEq)]
+   |                ^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-use.rs:11:12
+   |
+LL | impl const PartialEq for A {
+   |            ^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-use.rs:15:25
+   |
+LL | #[derive_const(Default, PartialEq)]
+   |                         ^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/derive-const-use.rs:16:14
+   |
+LL | #[derive_const(Default, PartialEq)]
+   |                ------- in this derive macro expansion
+LL | pub struct S((), A);
+   |              ^^ calling non-const function `<() as Default>::default`
+   |
+note: inside `<S as Default>::default`
+  --> $DIR/derive-const-use.rs:16:14
+   |
+LL | #[derive_const(Default, PartialEq)]
+   |                ------- in this derive macro expansion
+LL | pub struct S((), A);
+   |              ^^
+note: inside `_`
+  --> $DIR/derive-const-use.rs:18:35
+   |
+LL | const _: () = assert!(S((), A) == S::default());
+   |                                   ^^^^^^^^^^^^
+   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 8 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0080, E0635.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs
new file mode 100644
index 00000000000..c032c76d38f
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs
@@ -0,0 +1,14 @@
+//@ known-bug: #110395
+// FIXME(effects) check-pass
+
+#![feature(derive_const)]
+#![feature(const_trait_impl, effects)]
+
+#[derive_const(PartialEq)]
+pub struct Reverse<T>(T);
+
+const fn foo(a: Reverse<i32>, b: Reverse<i32>) -> bool {
+    a == b
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr
new file mode 100644
index 00000000000..addce8dcd6c
--- /dev/null
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr
@@ -0,0 +1,34 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/derive-const-with-params.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
+
+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/derive-const-with-params.rs:7:16
+   |
+LL | #[derive_const(PartialEq)]
+   |                ^^^^^^^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/derive-const-with-params.rs:7:16
+   |
+LL | #[derive_const(PartialEq)]
+   |                ^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs b/tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs
new file mode 100644
index 00000000000..9ee5254dbf8
--- /dev/null
+++ b/tests/ui/traits/const-traits/cross-crate-default-method-body-is-const.rs
@@ -0,0 +1,19 @@
+// This tests that `const_trait` default methods can
+// be called from a const context when used across crates.
+//
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+//@ aux-build: cross-crate.rs
+extern crate cross_crate;
+
+use cross_crate::*;
+
+const _: () = {
+    Const.func();
+    Const.defaulted_func();
+};
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
new file mode 100644
index 00000000000..a34bae843c8
--- /dev/null
+++ b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
+  --> $DIR/cross-crate.rs:19:14
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/cross-crate.rs b/tests/ui/traits/const-traits/cross-crate.rs
new file mode 100644
index 00000000000..cfcada9c828
--- /dev/null
+++ b/tests/ui/traits/const-traits/cross-crate.rs
@@ -0,0 +1,27 @@
+//@ revisions: stock gated stocknc gatednc
+//@ [gated] check-pass
+//@ compile-flags: -Znext-solver
+#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))]
+#![allow(incomplete_features)]
+
+//@ aux-build: cross-crate.rs
+extern crate cross_crate;
+
+use cross_crate::*;
+
+fn non_const_context() {
+    NonConst.func();
+    Const.func();
+}
+
+const fn const_context() {
+    #[cfg(any(stocknc, gatednc))]
+    NonConst.func();
+    //[stocknc]~^ ERROR: cannot call
+    //[gatednc]~^^ ERROR: the trait bound
+    Const.func();
+    //[stock]~^ ERROR: cannot call
+    //[stocknc]~^^ ERROR: cannot call
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr
new file mode 100644
index 00000000000..b481bdc470c
--- /dev/null
+++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr
@@ -0,0 +1,15 @@
+error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:22:11
+   |
+LL |     Const.func();
+   |           ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
new file mode 100644
index 00000000000..5c3e3b6ff40
--- /dev/null
+++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
@@ -0,0 +1,27 @@
+error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:19:14
+   |
+LL |     NonConst.func();
+   |              ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:22:11
+   |
+LL |     Const.func();
+   |           ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
new file mode 100644
index 00000000000..b534d23b107
--- /dev/null
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
@@ -0,0 +1,20 @@
+//@ known-bug: #110395
+//@ check-pass
+
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Tr {}
+impl Tr for () {}
+
+const fn foo<T>() where T: ~const Tr {}
+
+#[const_trait]
+pub trait Foo {
+    fn foo() {
+        foo::<()>();
+        //FIXME ~^ ERROR the trait bound `(): Tr` is not satisfied
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs
new file mode 100644
index 00000000000..0c2d93775a4
--- /dev/null
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+pub trait Tr {
+    fn a(&self) {}
+
+    fn b(&self) {
+        ().a()
+        //~^ ERROR the trait bound `(): ~const Tr` is not satisfied
+    }
+}
+
+impl Tr for () {}
+
+fn main() {}
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
new file mode 100644
index 00000000000..d0f22c0b9b6
--- /dev/null
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `(): ~const Tr` is not satisfied
+  --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs b/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs
new file mode 100644
index 00000000000..8b264ebd0e4
--- /dev/null
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs
@@ -0,0 +1,17 @@
+//@ check-pass
+
+// This was an ICE, because the compiler ensures the
+// function to be const when performing const checking,
+// but functions marked with the attribute are not const
+// *and* subject to const checking.
+
+#![feature(staged_api)]
+#![feature(const_trait_impl)]
+#![stable(feature = "foo", since = "3.3.3")]
+
+#[const_trait]
+trait Tr {
+    fn a() {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/do-not-const-check-override.rs b/tests/ui/traits/const-traits/do-not-const-check-override.rs
new file mode 100644
index 00000000000..71e6375283f
--- /dev/null
+++ b/tests/ui/traits/const-traits/do-not-const-check-override.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, rustc_attrs, effects)]
+
+#[const_trait]
+trait Foo {
+    #[rustc_do_not_const_check]
+    fn into_iter(&self) { println!("FEAR ME!") }
+}
+
+
+impl const Foo for () {
+    fn into_iter(&self) {
+        // ^_^
+    }
+}
+
+const _: () = Foo::into_iter(&());
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/do-not-const-check.rs b/tests/ui/traits/const-traits/do-not-const-check.rs
new file mode 100644
index 00000000000..443b6385735
--- /dev/null
+++ b/tests/ui/traits/const-traits/do-not-const-check.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+#![feature(const_trait_impl, rustc_attrs)]
+
+#[const_trait]
+trait IntoIter {
+    fn into_iter(self);
+}
+
+#[const_trait]
+trait Hmm: Sized {
+    #[rustc_do_not_const_check]
+    fn chain<U>(self, other: U) where U: IntoIter,
+    {
+        other.into_iter()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs b/tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs
new file mode 100644
index 00000000000..779527e22d4
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/auxiliary/cross-crate.rs
@@ -0,0 +1,14 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+pub const fn foo() {}
+
+#[const_trait]
+pub trait Bar {
+    fn bar();
+}
+
+impl Bar for () {
+    fn bar() {}
+}
diff --git a/tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs
new file mode 100644
index 00000000000..3debc22098a
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/const_closure-const_trait_impl-ice-113381.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+// FIXME(effects) this shouldn't pass
+//@ compile-flags: -Znext-solver
+#![feature(const_closures, const_trait_impl, effects)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    fn foo(&self);
+}
+
+impl Foo for () {
+    fn foo(&self) {}
+}
+
+fn main() {
+    (const || { (()).foo() })();
+    // FIXME(effects) ~^ ERROR: cannot call non-const fn
+}
diff --git a/tests/ui/traits/const-traits/effects/effect-param-infer.rs b/tests/ui/traits/const-traits/effects/effect-param-infer.rs
new file mode 100644
index 00000000000..958b9ac6d57
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/effect-param-infer.rs
@@ -0,0 +1,16 @@
+// Ensure that we don't get a mismatch error when inserting the host param
+// at the end of generic args when the generics have defaulted params.
+//
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+pub trait Foo<Rhs: ?Sized = Self> {
+    /* stuff */
+}
+
+impl const Foo for () {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/fallback.rs b/tests/ui/traits/const-traits/effects/fallback.rs
new file mode 100644
index 00000000000..4cfba00526b
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/fallback.rs
@@ -0,0 +1,17 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(effects)]
+
+pub const fn owo() {}
+
+fn main() {
+    // make sure falling back ty/int vars doesn't cause const fallback to be skipped...
+    // See issue: 115791.
+    let _ = 1;
+    if false {
+        let x = panic!();
+    }
+
+    let _ = owo;
+}
diff --git a/tests/ui/traits/const-traits/effects/group-traits.rs b/tests/ui/traits/const-traits/effects/group-traits.rs
new file mode 100644
index 00000000000..2c5b6cc40e6
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/group-traits.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+use std::ops::Add;
+
+pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> Add<&'r Rhs, Output = Output> {}
+
+pub trait Curve: Sized + GroupOpsOwned<Self::AffineRepr> {
+    type AffineRepr;
+}
+
+pub trait CofactorCurve: Curve<AffineRepr = <Self as CofactorCurve>::Affine> {
+    type Affine;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/helloworld.rs b/tests/ui/traits/const-traits/effects/helloworld.rs
new file mode 100644
index 00000000000..54f362b4413
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/helloworld.rs
@@ -0,0 +1,33 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+// gate-test-effects
+// ^ effects doesn't have a gate so we will trick tidy into thinking this is a gate test
+#![allow(incomplete_features)]
+#![feature(
+    const_trait_impl,
+    effects,
+    core_intrinsics,
+    const_eval_select
+)]
+
+// ensure we are passing in the correct host effect in always const contexts.
+
+pub const fn hmm<T>() -> usize {
+    // FIXME(const_trait_impl): maybe we should have a way to refer to the (hidden) effect param
+    fn one() -> usize { 1 }
+    const fn zero() -> usize { 0 }
+    unsafe {
+        std::intrinsics::const_eval_select((), zero, one)
+    }
+}
+
+const _: () = {
+    let x = hmm::<()>();
+    assert!(0 == x);
+};
+
+pub const fn uwu(x: [u8; hmm::<()>()]) {
+    let [] = x;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs
new file mode 100644
index 00000000000..9a9016de3a0
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs
@@ -0,0 +1,19 @@
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+const fn test() -> impl ~const Fn() {
+    //~^ ERROR `~const` can only be applied to `#[const_trait]` traits
+    //~| ERROR `~const` can only be applied to `#[const_trait]` traits
+    const move || { //~ ERROR const closures are experimental
+        let sl: &[u8] = b"foo";
+
+        match sl {
+            [first, remainder @ ..] => {
+                assert_eq!(first, &b'f');
+                //~^ ERROR cannot call non-const fn
+            }
+            [] => panic!(),
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr
new file mode 100644
index 00000000000..526746eec73
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr
@@ -0,0 +1,51 @@
+error[E0658]: const closures are experimental
+  --> $DIR/ice-112822-expected-type-for-param.rs:6:5
+   |
+LL |     const move || {
+   |     ^^^^^
+   |
+   = note: see issue #106003 <https://github.com/rust-lang/rust/issues/106003> for more information
+   = help: add `#![feature(const_closures)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/ice-112822-expected-type-for-param.rs:1: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` can only be applied to `#[const_trait]` traits
+  --> $DIR/ice-112822-expected-type-for-param.rs:3:32
+   |
+LL | const fn test() -> impl ~const Fn() {
+   |                                ^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/ice-112822-expected-type-for-param.rs:3:32
+   |
+LL | const fn test() -> impl ~const Fn() {
+   |                                ^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0015]: cannot call non-const fn `core::panicking::assert_failed::<&u8, &u8>` in constant functions
+  --> $DIR/ice-112822-expected-type-for-param.rs:11:17
+   |
+LL |                 assert_eq!(first, &b'f');
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs b/tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs
new file mode 100644
index 00000000000..06e3377c5ee
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/ice-113375-index-out-of-bounds-generics.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+// effects ice https://github.com/rust-lang/rust/issues/113375 index out of bounds
+
+#![allow(incomplete_features, unused)]
+#![feature(effects, adt_const_params)]
+
+struct Bar<T>(T);
+
+impl<T> Bar<T> {
+    const fn value() -> usize {
+        42
+    }
+}
+
+struct Foo<const N: [u8; Bar::<u32>::value()]>;
+
+pub fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/infer-fallback.rs b/tests/ui/traits/const-traits/effects/infer-fallback.rs
new file mode 100644
index 00000000000..581c3949d38
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/infer-fallback.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+const fn a() {}
+
+fn foo<F: FnOnce()>(a: F) {}
+
+fn main() {
+    let _ = a;
+    foo(a);
+}
diff --git a/tests/ui/traits/const-traits/effects/minicore.rs b/tests/ui/traits/const-traits/effects/minicore.rs
new file mode 100644
index 00000000000..1c3c66bc3ce
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/minicore.rs
@@ -0,0 +1,570 @@
+//@ known-bug: #110395
+//@ failure-status: 101
+//@ normalize-stderr-test: ".*note: .*\n\n" -> ""
+//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> ""
+//@ rustc-env:RUST_BACKTRACE=0
+// FIXME(effects) check-pass
+//@ compile-flags: -Znext-solver
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs, staged_api)]
+#![feature(fundamental, marker_trait_attr)]
+#![feature(const_trait_impl, effects)]
+#![allow(internal_features, incomplete_features)]
+#![no_std]
+#![no_core]
+#![stable(feature = "minicore", since = "1.0.0")]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "add"]
+#[const_trait]
+trait Add<Rhs = Self> {
+    type Output;
+
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+impl const Add for i32 {
+    type Output = i32;
+    fn add(self, rhs: i32) -> i32 {
+        loop {}
+    }
+}
+
+fn foo() {
+    let x = 42_i32 + 43_i32;
+}
+
+const fn bar() {
+    let x = 42_i32 + 43_i32;
+}
+
+
+#[lang = "Try"]
+#[const_trait]
+trait Try: FromResidual<Self::Residual> {
+    type Output;
+    type Residual;
+
+    #[lang = "from_output"]
+    fn from_output(output: Self::Output) -> Self;
+
+    #[lang = "branch"]
+    fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+}
+
+// FIXME
+// #[const_trait]
+trait FromResidual<R = <Self as /* FIXME: ~const */ Try>::Residual> {
+    #[lang = "from_residual"]
+    fn from_residual(residual: R) -> Self;
+}
+
+enum ControlFlow<B, C = ()> {
+    #[lang = "Continue"]
+    Continue(C),
+    #[lang = "Break"]
+    Break(B),
+}
+
+#[const_trait]
+#[lang = "fn"]
+#[rustc_paren_sugar]
+trait Fn<Args: Tuple>: ~const FnMut<Args> {
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[const_trait]
+#[lang = "fn_mut"]
+#[rustc_paren_sugar]
+trait FnMut<Args: Tuple>: ~const FnOnce<Args> {
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[const_trait]
+#[lang = "fn_once"]
+#[rustc_paren_sugar]
+trait FnOnce<Args: Tuple> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct ConstFnMutClosure<CapturedData, Function> {
+    data: CapturedData,
+    func: Function,
+}
+
+#[lang = "tuple_trait"]
+trait Tuple {}
+
+macro_rules! impl_fn_mut_tuple {
+    ($($var:ident)*) => {
+        impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
+            FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
+        where
+            Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue,
+            Function: ~const Destruct,
+        {
+            type Output = ClosureReturnValue;
+
+            extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
+            self.call_mut(args)
+            }
+        }
+        impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
+            FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
+        where
+            Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
+            Function: ~const Destruct,
+        {
+            extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
+                #[allow(non_snake_case)]
+                let ($($var),*) = &mut self.data;
+                (self.func)(($($var),*), args)
+            }
+        }
+    };
+}
+//impl_fn_mut_tuple!(A);
+//impl_fn_mut_tuple!(A B);
+//impl_fn_mut_tuple!(A B C);
+//impl_fn_mut_tuple!(A B C D);
+//impl_fn_mut_tuple!(A B C D E);
+
+#[lang = "receiver"]
+trait Receiver {}
+
+impl<T: ?Sized> Receiver for &T {}
+
+impl<T: ?Sized> Receiver for &mut T {}
+
+#[lang = "destruct"]
+#[const_trait]
+trait Destruct {}
+
+#[lang = "freeze"]
+unsafe auto trait Freeze {}
+
+#[lang = "drop"]
+#[const_trait]
+trait Drop {
+    fn drop(&mut self);
+}
+
+/*
+#[const_trait]
+trait Residual<O> {
+    type TryType: ~const Try<Output = O, Residual = Self> + Try<Output = O, Residual = Self>;
+}
+*/
+
+const fn size_of<T>() -> usize {
+    42
+}
+
+impl Copy for u8 {}
+
+impl usize {
+    #[rustc_allow_incoherent_impl]
+    const fn repeat_u8(x: u8) -> usize {
+        usize::from_ne_bytes([x; size_of::<usize>()])
+    }
+    #[rustc_allow_incoherent_impl]
+    const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
+        loop {}
+    }
+}
+
+#[rustc_do_not_const_check] // hooked by const-eval
+const fn panic_display() {
+    panic_fmt();
+}
+
+fn panic_fmt() {}
+
+#[lang = "index"]
+#[const_trait]
+trait Index<Idx: ?Sized> {
+    type Output: ?Sized;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+
+#[const_trait]
+unsafe trait SliceIndex<T: ?Sized> {
+    type Output: ?Sized;
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+impl<T, I> const Index<I> for [T]
+where
+    I: ~const SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    #[inline]
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+/* FIXME
+impl<T, I, const N: usize> const Index<I> for [T; N]
+where
+    [T]: ~const Index<I>,
+{
+    type Output = <[T] as Index<I>>::Output;
+
+    #[inline]
+    // FIXME: make `Self::Output` act like `<Self as ~const Index<I>>::Output`
+    fn index(&self, index: I) -> &<[T] as Index<I>>::Output {
+        Index::index(self as &[T], index)
+    }
+}
+*/
+
+#[lang = "unsize"]
+trait Unsize<T: ?Sized> {
+}
+
+#[lang = "coerce_unsized"]
+trait CoerceUnsized<T: ?Sized> {
+}
+
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+
+
+#[lang = "deref"]
+// #[const_trait] FIXME
+trait Deref {
+    #[lang = "deref_target"]
+    type Target: ?Sized;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+
+impl<T: ?Sized> /* const */ Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+impl<T: ?Sized> /* const */ Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+enum Option<T> {
+    #[lang = "None"]
+    None,
+    #[lang = "Some"]
+    Some(T),
+}
+
+impl<T> Option<T> {
+    const fn as_ref(&self) -> Option<&T> {
+        match *self {
+            Some(ref x) => Some(x),
+            None => None,
+        }
+    }
+
+    const fn as_mut(&mut self) -> Option<&mut T> {
+        match *self {
+            Some(ref mut x) => Some(x),
+            None => None,
+        }
+    }
+}
+
+use Option::*;
+
+/*
+const fn as_deref<T>(opt: &Option<T>) -> Option<&T::Target>
+where
+    T: ~const Deref,
+{
+    match opt {
+        Option::Some(t) => Option::Some(t.deref()),
+        Option::None => Option::None,
+    }
+}
+*/
+
+#[const_trait]
+trait Into<T>: Sized {
+    fn into(self) -> T;
+}
+
+#[const_trait]
+trait From<T>: Sized {
+    fn from(value: T) -> Self;
+}
+
+impl<T, U> const Into<U> for T
+where
+    U: ~const From<T>,
+{
+    fn into(self) -> U {
+        U::from(self)
+    }
+}
+
+impl<T> const From<T> for T {
+    fn from(t: T) -> T {
+        t
+    }
+}
+
+enum Result<T, E> {
+    Ok(T),
+    Err(E),
+}
+use Result::*;
+
+fn from_str(s: &str) -> Result<bool, ()> {
+    match s {
+        "true" => Ok(true),
+        "false" => Ok(false),
+        _ => Err(()),
+    }
+}
+
+#[lang = "eq"]
+#[const_trait]
+trait PartialEq<Rhs: ?Sized = Self> {
+    fn eq(&self, other: &Rhs) -> bool;
+    fn ne(&self, other: &Rhs) -> bool {
+        !self.eq(other)
+    }
+}
+
+impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A
+where
+    A: ~const PartialEq<B>,
+{
+    fn eq(&self, other: &&B) -> bool {
+        PartialEq::eq(*self, *other)
+    }
+}
+
+impl PartialEq for str {
+    fn eq(&self, other: &str) -> bool {
+        loop {}
+    }
+}
+
+
+#[lang = "not"]
+#[const_trait]
+trait Not {
+    type Output;
+    fn not(self) -> Self::Output;
+}
+
+impl const Not for bool {
+    type Output = bool;
+    fn not(self) -> bool {
+        !self
+    }
+}
+
+impl Copy for bool {}
+impl<'a> Copy for &'a str {}
+
+#[lang = "pin"]
+#[fundamental]
+#[repr(transparent)]
+struct Pin<P> {
+    pointer: P,
+}
+
+impl<P> Pin<P> {
+    #[lang = "new_unchecked"]
+    const unsafe fn new_unchecked(pointer: P) -> Pin<P> {
+        Pin { pointer }
+    }
+}
+
+impl<'a, T: ?Sized> Pin<&'a T> {
+    const fn get_ref(self) -> &'a T {
+        self.pointer
+    }
+}
+
+
+impl<P: Deref> Pin<P> {
+    /* const */ fn as_ref(&self) -> Pin<&P::Target>
+    where
+        P: /* ~const */ Deref,
+    {
+        unsafe { Pin::new_unchecked(&*self.pointer) }
+    }
+}
+
+
+impl<'a, T: ?Sized> Pin<&'a mut T> {
+    const unsafe fn get_unchecked_mut(self) -> &'a mut T {
+        self.pointer
+    }
+}
+/* FIXME lol
+impl<T> Option<T> {
+    const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
+        match Pin::get_ref(self).as_ref() {
+            Some(x) => unsafe { Some(Pin::new_unchecked(x)) },
+            None => None,
+        }
+    }
+
+    const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
+        unsafe {
+            match Pin::get_unchecked_mut(self).as_mut() {
+                Some(x) => Some(Pin::new_unchecked(x)),
+                None => None,
+            }
+        }
+    }
+}
+*/
+
+impl<P: /* ~const */ Deref> /* const */ Deref for Pin<P> {
+    type Target = P::Target;
+    fn deref(&self) -> &P::Target {
+        Pin::get_ref(Pin::as_ref(self))
+    }
+}
+
+impl<T> /* const */ Deref for Option<T> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        loop {}
+    }
+}
+
+impl<P: Receiver> Receiver for Pin<P> {}
+
+impl<T: Clone> Clone for RefCell<T> {
+    fn clone(&self) -> RefCell<T> {
+        RefCell::new(self.borrow().clone())
+    }
+}
+
+struct RefCell<T: ?Sized> {
+    borrow: UnsafeCell<()>,
+    value: UnsafeCell<T>,
+}
+impl<T> RefCell<T> {
+    const fn new(value: T) -> RefCell<T> {
+        loop {}
+    }
+}
+impl<T: ?Sized> RefCell<T> {
+    fn borrow(&self) -> Ref<'_, T> {
+        loop {}
+    }
+}
+
+#[lang = "unsafe_cell"]
+#[repr(transparent)]
+struct UnsafeCell<T: ?Sized> {
+    value: T,
+}
+
+struct Ref<'b, T: ?Sized + 'b> {
+    value: *const T,
+    borrow: &'b UnsafeCell<()>,
+}
+
+impl<T: ?Sized> Deref for Ref<'_, T> {
+    type Target = T;
+
+    #[inline]
+    fn deref(&self) -> &T {
+        loop {}
+    }
+}
+
+#[lang = "clone"]
+#[rustc_trivial_field_reads]
+#[const_trait]
+trait Clone: Sized {
+    fn clone(&self) -> Self;
+    fn clone_from(&mut self, source: &Self)
+    where
+        Self: ~const Destruct,
+    {
+        *self = source.clone()
+    }
+}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+const fn drop<T: ~const Destruct>(_: T) {}
+
+#[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_intrinsic]
+const fn const_eval_select<ARG: Tuple, F, G, RET>(
+    arg: ARG,
+    called_in_const: F,
+    called_at_rt: G,
+) -> RET
+where
+    F: const FnOnce<ARG, Output = RET>,
+    G: FnOnce<ARG, Output = RET>,
+{
+    loop {}
+}
+
+fn test_const_eval_select() {
+    const fn const_fn() {}
+    fn rt_fn() {}
+
+    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
new file mode 100644
index 00000000000..823ab69df9c
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/minicore.stderr
@@ -0,0 +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
+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
+end of query stack
diff --git a/tests/ui/traits/const-traits/effects/mismatched_generic_args.rs b/tests/ui/traits/const-traits/effects/mismatched_generic_args.rs
new file mode 100644
index 00000000000..21e91c731b3
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/mismatched_generic_args.rs
@@ -0,0 +1,24 @@
+#![feature(generic_const_exprs)]
+//~^ WARN: the feature `generic_const_exprs` is incomplete
+
+// Regression test for #125770 which would ICE under the old effects desugaring that
+// created a const generic parameter for constness on `Add`.
+
+use std::ops::Add;
+
+pub struct Dimension;
+
+pub struct Quantity<S, const D: Dimension>(S);
+//~^ ERROR: `Dimension` is forbidden as the type of a const generic parameter
+
+impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
+//~^ ERROR: trait takes at most 1 generic argument
+//~| ERROR: `Dimension` is forbidden as the type of a const generic parameter
+
+pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
+    //~^ ERROR: `Dimension` is forbidden as the type of a const generic parameter
+    x + y
+    //~^ ERROR: cannot find value `y` in this scope
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr b/tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr
new file mode 100644
index 00000000000..8e12b40381f
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/mismatched_generic_args.stderr
@@ -0,0 +1,64 @@
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/mismatched_generic_args.rs:20:9
+   |
+LL | pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
+   |                  - similarly named const parameter `U` defined here
+LL |
+LL |     x + y
+   |         ^ help: a const parameter with a similar name exists: `U`
+
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/mismatched_generic_args.rs:1:12
+   |
+LL | #![feature(generic_const_exprs)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: `Dimension` is forbidden as the type of a const generic parameter
+  --> $DIR/mismatched_generic_args.rs:11:33
+   |
+LL | pub struct Quantity<S, const D: Dimension>(S);
+   |                                 ^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error[E0107]: trait takes at most 1 generic argument but 2 generic arguments were supplied
+  --> $DIR/mismatched_generic_args.rs:14:36
+   |
+LL | impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
+   |                                    ^^^ expected at most 1 generic argument
+
+error: `Dimension` is forbidden as the type of a const generic parameter
+  --> $DIR/mismatched_generic_args.rs:14:15
+   |
+LL | impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
+   |               ^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error: `Dimension` is forbidden as the type of a const generic parameter
+  --> $DIR/mismatched_generic_args.rs:18:21
+   |
+LL | pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
+   |                     ^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0107, E0425.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs
new file mode 100644
index 00000000000..97052a1d09a
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.rs
@@ -0,0 +1,18 @@
+//@ aux-build: cross-crate.rs
+extern crate cross_crate;
+
+use cross_crate::{Bar, foo};
+
+fn main() {
+    foo::<true>();
+    //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
+    <() as Bar<true>>::bar();
+    //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+}
+
+const FOO: () = {
+    foo::<false>();
+    //~^ 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
+};
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
new file mode 100644
index 00000000000..8c591edac54
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr
@@ -0,0 +1,63 @@
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:14:5
+   |
+LL |     foo::<false>();
+   |     ^^^--------- help: remove the unnecessary generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/auxiliary/cross-crate.rs:5:14
+   |
+LL | pub const fn foo() {}
+   |              ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:16:12
+   |
+LL |     <() as Bar<false>>::bar();
+   |            ^^^ 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
+   |
+LL |     foo::<true>();
+   |     ^^^-------- help: remove the unnecessary generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/auxiliary/cross-crate.rs:5:14
+   |
+LL | pub const fn foo() {}
+   |              ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:9:12
+   |
+LL |     <() as Bar<true>>::bar();
+   |            ^^^ 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
+
+For more information about this error, try `rustc --explain E0107`.
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
new file mode 100644
index 00000000000..84f5f2803e1
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs
@@ -0,0 +1,27 @@
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+const fn foo() {}
+
+#[const_trait]
+trait Bar {
+    fn bar();
+}
+
+impl Bar for () {
+    fn bar() {}
+}
+
+fn main() {
+    foo::<true>();
+    //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
+    <() as Bar<true>>::bar();
+    //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+}
+
+const FOO: () = {
+    foo::<false>();
+    //~^ 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
new file mode 100644
index 00000000000..cc08114ddb5
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr
@@ -0,0 +1,87 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/no-explicit-const-params.rs:1: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[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:22:5
+   |
+LL |     foo::<false>();
+   |     ^^^--------- help: remove the unnecessary generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/no-explicit-const-params.rs:3:10
+   |
+LL | const fn foo() {}
+   |          ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:24:12
+   |
+LL |     <() as Bar<false>>::bar();
+   |            ^^^ 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
+   |
+LL |     foo::<true>();
+   |     ^^^-------- help: remove the unnecessary generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/no-explicit-const-params.rs:3:10
+   |
+LL | const fn foo() {}
+   |          ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:17:12
+   |
+LL |     <() as Bar<true>>::bar();
+   |            ^^^ 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
+
+Some errors have detailed explanations: E0107, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/const-traits/effects/project.rs b/tests/ui/traits/const-traits/effects/project.rs
new file mode 100644
index 00000000000..9f6ca1f294f
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/project.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![feature(const_trait_impl, effects)]
+#![allow(incomplete_features)]
+
+#[const_trait]
+pub trait Owo<X = <Self as Uwu>::T> {}
+
+#[const_trait]
+pub trait Uwu: Owo {
+    type T;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs
new file mode 100644
index 00000000000..e6e41c472bd
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.rs
@@ -0,0 +1,14 @@
+#![feature(const_trait_impl)]
+#![feature(effects)] //~ WARN the feature `effects` is incomplete
+
+struct S;
+trait T {}
+
+impl const dyn T {
+    //~^ ERROR inherent impls cannot be `const`
+    pub const fn new() -> std::sync::Mutex<dyn T> {}
+    //~^ ERROR mismatched types
+    //~| ERROR cannot be known at compilation time
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr
new file mode 100644
index 00000000000..5ff1c6c5b9f
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/span-bug-issue-121418.stderr
@@ -0,0 +1,50 @@
+error: inherent impls cannot be `const`
+  --> $DIR/span-bug-issue-121418.rs:7:12
+   |
+LL | impl const dyn T {
+   |      ----- ^^^^^ inherent impl for this type
+   |      |
+   |      `const` because of this
+   |
+   = note: only trait implementations may be annotated with `const`
+
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/span-bug-issue-121418.rs:2:12
+   |
+LL | #![feature(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[E0308]: mismatched types
+  --> $DIR/span-bug-issue-121418.rs:9:27
+   |
+LL |     pub const fn new() -> std::sync::Mutex<dyn T> {}
+   |                  ---      ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()`
+   |                  |
+   |                  implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note: expected struct `Mutex<(dyn T + 'static)>`
+           found unit type `()`
+
+error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
+  --> $DIR/span-bug-issue-121418.rs:9:27
+   |
+LL |     pub const fn new() -> std::sync::Mutex<dyn T> {}
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `Mutex<(dyn T + 'static)>`, the trait `Sized` is not implemented for `(dyn T + 'static)`, which is required by `Mutex<(dyn T + 'static)>: Sized`
+note: required because it appears within the type `Mutex<(dyn T + 'static)>`
+  --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
+   = note: the return type of a function must have a statically known size
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
new file mode 100644
index 00000000000..0508b1c5e26
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs
@@ -0,0 +1,21 @@
+//@ check-fail
+// Fixes #119830
+
+#![feature(effects)] //~ WARN the feature `effects` is incomplete
+#![feature(min_specialization)]
+#![feature(const_trait_impl)]
+
+trait Specialize {}
+
+trait Foo {}
+
+impl<T> const Foo for T {}
+//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+
+impl<T> const Foo for T where T: const Specialize {}
+//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+//~| error: `const` can only be applied to `#[const_trait]` traits
+//~| error: specialization impl does not specialize any associated items
+//~| error: cannot specialize on trait `Specialize`
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
new file mode 100644
index 00000000000..e97a9615ae1
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr
@@ -0,0 +1,64 @@
+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
+   |
+LL | #![feature(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 `Foo` which is not marked with `#[const_trait]`
+  --> $DIR/spec-effectvar-ice.rs:12:15
+   |
+LL | trait Foo {}
+   | - help: mark `Foo` as const: `#[const_trait]`
+LL |
+LL | impl<T> const Foo for T {}
+   |               ^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+  --> $DIR/spec-effectvar-ice.rs:15:15
+   |
+LL | trait Foo {}
+   | - help: mark `Foo` as const: `#[const_trait]`
+...
+LL | impl<T> const Foo for T where T: const Specialize {}
+   |               ^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: `const` can only be applied to `#[const_trait]` traits
+  --> $DIR/spec-effectvar-ice.rs:15: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
+   |
+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
+   |
+LL | impl<T> const Foo for T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot specialize on trait `Specialize`
+  --> $DIR/spec-effectvar-ice.rs:15:34
+   |
+LL | impl<T> const Foo for T where T: const Specialize {}
+   |                                  ^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/effects/trait-fn-const.rs b/tests/ui/traits/const-traits/effects/trait-fn-const.rs
new file mode 100644
index 00000000000..d63dbfbf57d
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/trait-fn-const.rs
@@ -0,0 +1,21 @@
+// Regression test for issue #113378.
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+#[const_trait]
+trait Trait {
+    const fn fun(); //~ ERROR functions in traits cannot be declared const
+}
+
+impl const Trait for () {
+    const fn fun() {} //~ ERROR functions in trait impls cannot be declared const
+}
+
+impl Trait for u32 {
+    const fn fun() {} //~ ERROR functions in trait impls cannot be declared const
+}
+
+trait NonConst {
+    const fn fun(); //~ ERROR functions in traits cannot be declared const
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/trait-fn-const.stderr b/tests/ui/traits/const-traits/effects/trait-fn-const.stderr
new file mode 100644
index 00000000000..15cb84026e4
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/trait-fn-const.stderr
@@ -0,0 +1,73 @@
+error[E0379]: functions in traits cannot be declared const
+  --> $DIR/trait-fn-const.rs:6:5
+   |
+LL | #[const_trait]
+   | -------------- this declares all associated functions implicitly const
+LL | trait Trait {
+LL |     const fn fun();
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
+
+error[E0379]: functions in trait impls cannot be declared const
+  --> $DIR/trait-fn-const.rs:10:5
+   |
+LL | impl const Trait for () {
+   |      ----- this declares all associated functions implicitly const
+LL |     const fn fun() {}
+   |     ^^^^^-
+   |     |
+   |     functions in trait impls cannot be const
+   |     help: remove the `const`
+
+error[E0379]: functions in trait impls cannot be declared const
+  --> $DIR/trait-fn-const.rs:14:5
+   |
+LL |     const fn fun() {}
+   |     ^^^^^ functions in trait impls cannot be const
+   |
+help: remove the `const` ...
+   |
+LL -     const fn fun() {}
+LL +     fn fun() {}
+   |
+help: ... and declare the impl to be const instead
+   |
+LL | impl const Trait for u32 {
+   |      +++++
+
+error[E0379]: functions in traits cannot be declared const
+  --> $DIR/trait-fn-const.rs:18:5
+   |
+LL |     const fn fun();
+   |     ^^^^^ functions in traits cannot be const
+   |
+help: remove the `const` ...
+   |
+LL -     const fn fun();
+LL +     fn fun();
+   |
+help: ... and declare the trait to be a `#[const_trait]` instead
+   |
+LL + #[const_trait]
+LL | trait NonConst {
+   |
+
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/trait-fn-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: 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 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0379`.
diff --git a/tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr b/tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr
new file mode 100644
index 00000000000..20448f51de2
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/with-without-next-solver.coherence.stderr
@@ -0,0 +1,7 @@
+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 1 previous error
+
diff --git a/tests/ui/traits/const-traits/effects/with-without-next-solver.rs b/tests/ui/traits/const-traits/effects/with-without-next-solver.rs
new file mode 100644
index 00000000000..f022af05c50
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/with-without-next-solver.rs
@@ -0,0 +1,10 @@
+// test that we error correctly when effects is used without the next-solver flag.
+//@ revisions: stock coherence full
+//@[coherence] compile-flags: -Znext-solver=coherence
+//@[full] compile-flags: -Znext-solver
+//@[full] check-pass
+
+#![feature(effects)]
+#![allow(incomplete_features)]
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr b/tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr
new file mode 100644
index 00000000000..20448f51de2
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/with-without-next-solver.stock.stderr
@@ -0,0 +1,7 @@
+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 1 previous error
+
diff --git a/tests/ui/traits/const-traits/feature-gate.gated.stderr b/tests/ui/traits/const-traits/feature-gate.gated.stderr
new file mode 100644
index 00000000000..12f9355e41d
--- /dev/null
+++ b/tests/ui/traits/const-traits/feature-gate.gated.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/feature-gate.rs:22:1
+   |
+LL | fn main() {}
+   | ^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/traits/const-traits/feature-gate.rs b/tests/ui/traits/const-traits/feature-gate.rs
new file mode 100644
index 00000000000..c36ec3538c3
--- /dev/null
+++ b/tests/ui/traits/const-traits/feature-gate.rs
@@ -0,0 +1,22 @@
+//@ revisions: stock gated
+// gate-test-const_trait_impl
+
+#![cfg_attr(gated, feature(const_trait_impl))]
+#![feature(rustc_attrs)]
+
+struct S;
+#[const_trait] //[stock]~ ERROR `const_trait` is a temporary placeholder
+trait T {}
+impl const T for S {}
+//[stock]~^ ERROR const trait impls are experimental
+
+const fn f<A: ~const T>() {} //[stock]~ ERROR const trait impls are experimental
+fn g<A: const T>() {} //[stock]~ ERROR const trait impls are experimental
+
+macro_rules! discard { ($ty:ty) => {} }
+
+discard! { impl ~const T } //[stock]~ ERROR const trait impls are experimental
+discard! { impl const T } //[stock]~ ERROR const trait impls are experimental
+
+#[rustc_error]
+fn main() {} //[gated]~ ERROR fatal error triggered by #[rustc_error]
diff --git a/tests/ui/traits/const-traits/feature-gate.stock.stderr b/tests/ui/traits/const-traits/feature-gate.stock.stderr
new file mode 100644
index 00000000000..78157d57056
--- /dev/null
+++ b/tests/ui/traits/const-traits/feature-gate.stock.stderr
@@ -0,0 +1,63 @@
+error[E0658]: const trait impls are experimental
+  --> $DIR/feature-gate.rs:10:6
+   |
+LL | impl const T for S {}
+   |      ^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/feature-gate.rs:13:15
+   |
+LL | const fn f<A: ~const T>() {}
+   |               ^^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/feature-gate.rs:14:9
+   |
+LL | fn g<A: const T>() {}
+   |         ^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/feature-gate.rs:18:17
+   |
+LL | discard! { impl ~const T }
+   |                 ^^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/feature-gate.rs:19:17
+   |
+LL | discard! { impl const T }
+   |                 ^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future.
+  --> $DIR/feature-gate.rs:8:1
+   |
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs b/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs
new file mode 100644
index 00000000000..61826e9977e
--- /dev/null
+++ b/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+#![feature(const_trait_impl)]
+
+#[const_trait]
+pub trait Test {}
+
+impl Test for () {}
+
+pub const fn test<T: ~const Test>() {}
+
+pub const fn min_by_i32() -> fn() {
+    test::<()>
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/gate.rs b/tests/ui/traits/const-traits/gate.rs
new file mode 100644
index 00000000000..d1c93ab9f95
--- /dev/null
+++ b/tests/ui/traits/const-traits/gate.rs
@@ -0,0 +1,13 @@
+// gate-test-const_closures
+
+fn main() {
+    (const || {})();
+    //~^ ERROR: const closures are experimental
+}
+
+macro_rules! e {
+    ($e:expr) => {}
+}
+
+e!((const || {}));
+//~^ ERROR const closures are experimental
diff --git a/tests/ui/traits/const-traits/gate.stderr b/tests/ui/traits/const-traits/gate.stderr
new file mode 100644
index 00000000000..19fd54ff369
--- /dev/null
+++ b/tests/ui/traits/const-traits/gate.stderr
@@ -0,0 +1,23 @@
+error[E0658]: const closures are experimental
+  --> $DIR/gate.rs:4:6
+   |
+LL |     (const || {})();
+   |      ^^^^^
+   |
+   = note: see issue #106003 <https://github.com/rust-lang/rust/issues/106003> for more information
+   = help: add `#![feature(const_closures)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const closures are experimental
+  --> $DIR/gate.rs:12:5
+   |
+LL | e!((const || {}));
+   |     ^^^^^
+   |
+   = note: see issue #106003 <https://github.com/rust-lang/rust/issues/106003> for more information
+   = help: add `#![feature(const_closures)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/generic-bound.rs b/tests/ui/traits/const-traits/generic-bound.rs
new file mode 100644
index 00000000000..620e3259917
--- /dev/null
+++ b/tests/ui/traits/const-traits/generic-bound.rs
@@ -0,0 +1,30 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl)]
+
+use std::marker::PhantomData;
+
+struct S<T>(PhantomData<T>);
+
+impl<T> Copy for S<T> {}
+impl<T> Clone for S<T> {
+    fn clone(&self) -> Self {
+        S(PhantomData)
+    }
+}
+
+impl<T> const std::ops::Add for S<T> {
+    type Output = Self;
+
+    fn add(self, _: Self) -> Self {
+        S(std::marker::PhantomData)
+    }
+}
+
+const fn twice<T: std::ops::Add>(arg: S<T>) -> S<T> {
+    arg + arg
+}
+
+fn main() {
+    let _ = twice(S(PhantomData::<i32>));
+}
diff --git a/tests/ui/traits/const-traits/generic-bound.stderr b/tests/ui/traits/const-traits/generic-bound.stderr
new file mode 100644
index 00000000000..2baac1d2a16
--- /dev/null
+++ b/tests/ui/traits/const-traits/generic-bound.stderr
@@ -0,0 +1,24 @@
+error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
+  --> $DIR/generic-bound.rs:16:15
+   |
+LL | impl<T> const std::ops::Add for S<T> {
+   |               ^^^^^^^^^^^^^
+   |
+   = 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[E0015]: cannot call non-const operator in constant functions
+  --> $DIR/generic-bound.rs:25:5
+   |
+LL |     arg + arg
+   |     ^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/hir-const-check.rs b/tests/ui/traits/const-traits/hir-const-check.rs
new file mode 100644
index 00000000000..f5fb0fd516a
--- /dev/null
+++ b/tests/ui/traits/const-traits/hir-const-check.rs
@@ -0,0 +1,17 @@
+// Regression test for #69615.
+
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+#[const_trait]
+pub trait MyTrait {
+    fn method(&self) -> Option<()>;
+}
+
+impl const MyTrait for () {
+    fn method(&self) -> Option<()> {
+        Some(())?; //~ ERROR `?` is not allowed in a `const fn`
+        None
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/hir-const-check.stderr b/tests/ui/traits/const-traits/hir-const-check.stderr
new file mode 100644
index 00000000000..598129d8694
--- /dev/null
+++ b/tests/ui/traits/const-traits/hir-const-check.stderr
@@ -0,0 +1,27 @@
+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
+   |
+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[E0658]: `?` is not allowed in a `const fn`
+  --> $DIR/hir-const-check.rs:12:9
+   |
+LL |         Some(())?;
+   |         ^^^^^^^^^
+   |
+   = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information
+   = 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
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs
new file mode 100644
index 00000000000..c2f452a9925
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs
@@ -0,0 +1,15 @@
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects, try_trait_v2)]
+
+use std::ops::FromResidual;
+
+impl<T> const FromResidual for T {
+    //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
+    //~| type parameter `T` must be used as the type parameter for some local type
+    fn from_residual(t: T) -> _ {
+        //~^ the placeholder `_` is not allowed
+        t
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr
new file mode 100644
index 00000000000..50cdded8d51
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr
@@ -0,0 +1,38 @@
+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/ice-119717-constant-lifetime.rs:6:15
+   |
+LL | impl<T> const FromResidual for T {
+   |               ^^^^^^^^^^^^
+   |
+   = 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[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+  --> $DIR/ice-119717-constant-lifetime.rs:6:6
+   |
+LL | impl<T> const FromResidual for T {
+   |      ^ type parameter `T` must be used as the type parameter for some local type
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+   = note: only traits defined in the current crate can be implemented for a type parameter
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/ice-119717-constant-lifetime.rs:9:31
+   |
+LL |     fn from_residual(t: T) -> _ {
+   |                               ^ not allowed in type signatures
+   |
+help: try replacing `_` with the type in the corresponding trait method signature
+   |
+LL |     fn from_residual(t: T) -> T {
+   |                               ~
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0121, E0210.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/traits/const-traits/ice-120503-async-const-method.rs b/tests/ui/traits/const-traits/ice-120503-async-const-method.rs
new file mode 100644
index 00000000000..9cd18d4566d
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.rs
@@ -0,0 +1,17 @@
+//@ edition: 2021
+#![feature(effects)] //~ WARN the feature `effects` is incomplete
+
+trait MyTrait {}
+
+impl MyTrait for i32 {
+    async const fn bar(&self) {
+        //~^ ERROR expected one of `extern`
+        //~| ERROR functions in trait impls cannot be declared const
+        //~| ERROR functions cannot be both `const` and `async`
+        //~| ERROR method `bar` is not a member
+        main8().await;
+        //~^ ERROR cannot find function
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
new file mode 100644
index 00000000000..90771c344b5
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr
@@ -0,0 +1,75 @@
+error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
+  --> $DIR/ice-120503-async-const-method.rs:7:11
+   |
+LL |     async const fn bar(&self) {
+   |     ------^^^^^
+   |     |     |
+   |     |     expected one of `extern`, `fn`, `safe`, or `unsafe`
+   |     help: `const` must come before `async`: `const async`
+   |
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+error[E0379]: functions in trait impls cannot be declared const
+  --> $DIR/ice-120503-async-const-method.rs:7:11
+   |
+LL |     async const fn bar(&self) {
+   |           ^^^^^-
+   |           |
+   |           functions in trait impls cannot be const
+   |           help: remove the `const`
+
+error: functions cannot be both `const` and `async`
+  --> $DIR/ice-120503-async-const-method.rs:7:5
+   |
+LL |       async const fn bar(&self) {
+   |       -^^^^ ^^^^^ `const` because of this
+   |       |
+   |  _____`async` because of this
+   | |
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | |     }
+   | |_____-
+
+error[E0407]: method `bar` is not a member of trait `MyTrait`
+  --> $DIR/ice-120503-async-const-method.rs:7:5
+   |
+LL | /     async const fn bar(&self) {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | |     }
+   | |_____^ not a member of trait `MyTrait`
+
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/ice-120503-async-const-method.rs:2:12
+   |
+LL | #![feature(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[E0425]: cannot find function `main8` in this scope
+  --> $DIR/ice-120503-async-const-method.rs:12:9
+   |
+LL |         main8().await;
+   |         ^^^^^ help: a function with a similar name exists: `main`
+...
+LL | fn main() {}
+   | --------- similarly named function `main` defined here
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0379, E0407, E0425.
+For more information about an error, try `rustc --explain E0379`.
diff --git a/tests/ui/traits/const-traits/ice-121536-const-method.rs b/tests/ui/traits/const-traits/ice-121536-const-method.rs
new file mode 100644
index 00000000000..a01329278d7
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-121536-const-method.rs
@@ -0,0 +1,17 @@
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+
+pub struct Vec3;
+
+#[const_trait]
+pub trait Add {
+    fn add(self) -> Vec3;
+}
+
+impl Add for Vec3 {
+    const fn add(self) -> Vec3 {
+        //~^ ERROR functions in trait impls cannot be declared const
+        self
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-121536-const-method.stderr b/tests/ui/traits/const-traits/ice-121536-const-method.stderr
new file mode 100644
index 00000000000..29187654c3c
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-121536-const-method.stderr
@@ -0,0 +1,33 @@
+error[E0379]: functions in trait impls cannot be declared const
+  --> $DIR/ice-121536-const-method.rs:11:5
+   |
+LL |     const fn add(self) -> Vec3 {
+   |     ^^^^^ functions in trait impls cannot be const
+   |
+help: remove the `const` ...
+   |
+LL -     const fn add(self) -> Vec3 {
+LL +     fn add(self) -> Vec3 {
+   |
+help: ... and declare the impl to be const instead
+   |
+LL | impl const Add for Vec3 {
+   |      +++++
+
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/ice-121536-const-method.rs:1: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: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0379`.
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
new file mode 100644
index 00000000000..64634e7b7ac
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs
@@ -0,0 +1,7 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs, const_trait_impl, effects)]
+
+const fn with_positive<F: ~const Fn()>() {}
+//~^ 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
new file mode 100644
index 00000000000..c937430a1ca
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr
@@ -0,0 +1,13 @@
+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/ice-123664-unexpected-bound-var.rs:4:34
+   |
+LL | const fn with_positive<F: ~const Fn()>() {}
+   |                                  ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs
new file mode 100644
index 00000000000..d4fcbfb1b83
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs
@@ -0,0 +1,14 @@
+//@ compile-flags: -Znext-solver=coherence
+
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Foo {}
+
+impl const Foo for i32 {}
+
+impl<T> const Foo for T where T: ~const Foo {}
+//~^ ERROR conflicting implementations of trait `Foo` for type `i32`
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr
new file mode 100644
index 00000000000..284757c1a89
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr
@@ -0,0 +1,17 @@
+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[E0119]: conflicting implementations of trait `Foo` for type `i32`
+  --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1
+   |
+LL | impl const Foo for i32 {}
+   | ---------------------- first implementation here
+LL |
+LL | impl<T> const Foo for T where T: ~const Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs
new file mode 100644
index 00000000000..717c0e7c088
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs
@@ -0,0 +1,28 @@
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects, try_trait_v2, const_try)]
+use std::ops::{FromResidual, Try};
+
+struct TryMe;
+struct Error;
+
+impl const FromResidual<Error> for TryMe {}
+//~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
+//~| ERROR not all trait items implemented
+
+impl const Try for TryMe {
+    //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]`
+    //~| ERROR not all trait items implemented
+    type Output = ();
+    type Residual = Error;
+}
+
+const fn t() -> TryMe {
+    TryMe?;
+    TryMe
+}
+
+const _: () = {
+    t();
+};
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr
new file mode 100644
index 00000000000..e49436c8f0f
--- /dev/null
+++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr
@@ -0,0 +1,43 @@
+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/ice-126148-failed-to-normalize.rs:8:12
+   |
+LL | impl const FromResidual<Error> 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[E0046]: not all trait items implemented, missing: `from_residual`
+  --> $DIR/ice-126148-failed-to-normalize.rs:8:1
+   |
+LL | impl const FromResidual<Error> for TryMe {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_residual` in implementation
+   |
+   = help: implement the missing item: `fn from_residual(_: Error) -> Self { todo!() }`
+
+error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
+  --> $DIR/ice-126148-failed-to-normalize.rs:12:12
+   |
+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[E0046]: not all trait items implemented, missing: `from_output`, `branch`
+  --> $DIR/ice-126148-failed-to-normalize.rs:12:1
+   |
+LL | impl const Try for TryMe {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_output`, `branch` in implementation
+   |
+   = help: implement the missing item: `fn from_output(_: <Self as Try>::Output) -> Self { todo!() }`
+   = help: implement the missing item: `fn branch(self) -> ControlFlow<<Self as Try>::Residual, <Self as Try>::Output> { todo!() }`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/traits/const-traits/impl-tilde-const-trait.rs b/tests/ui/traits/const-traits/impl-tilde-const-trait.rs
new file mode 100644
index 00000000000..05b26465c5b
--- /dev/null
+++ b/tests/ui/traits/const-traits/impl-tilde-const-trait.rs
@@ -0,0 +1,9 @@
+#![feature(const_trait_impl)]
+
+struct S;
+trait T {}
+
+impl ~const T for S {}
+//~^ ERROR expected a trait, found type
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/impl-tilde-const-trait.stderr b/tests/ui/traits/const-traits/impl-tilde-const-trait.stderr
new file mode 100644
index 00000000000..4695728f8ca
--- /dev/null
+++ b/tests/ui/traits/const-traits/impl-tilde-const-trait.stderr
@@ -0,0 +1,8 @@
+error: expected a trait, found type
+  --> $DIR/impl-tilde-const-trait.rs:6:6
+   |
+LL | impl ~const T for S {}
+   |      ^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs b/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs
new file mode 100644
index 00000000000..49741ca24c7
--- /dev/null
+++ b/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs
@@ -0,0 +1,18 @@
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Tr {
+    fn req(&self);
+
+    fn default() {}
+}
+
+struct S;
+
+impl const Tr for u16 {
+    fn default() {}
+} //~^^ ERROR not all trait items implemented
+
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr b/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr
new file mode 100644
index 00000000000..2ea203627f4
--- /dev/null
+++ b/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr
@@ -0,0 +1,17 @@
+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[E0046]: not all trait items implemented, missing: `req`
+  --> $DIR/impl-with-default-fn-fail.rs:13:1
+   |
+LL |     fn req(&self);
+   |     -------------- `req` from trait
+...
+LL | impl const Tr for u16 {
+   | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs b/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs
new file mode 100644
index 00000000000..2c375036941
--- /dev/null
+++ b/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Tr {
+    fn req(&self);
+
+    fn default() {}
+}
+
+impl const Tr for u8 {
+    fn req(&self) {}
+}
+
+macro_rules! impl_tr {
+    ($ty: ty) => {
+        impl const Tr for $ty {
+            fn req(&self) {}
+        }
+    }
+}
+
+impl_tr!(u64);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs b/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs
new file mode 100644
index 00000000000..5ead1353bcd
--- /dev/null
+++ b/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs
@@ -0,0 +1,22 @@
+//@ check-pass
+#![feature(const_trait_impl)]
+
+struct S;
+
+#[const_trait]
+trait A {}
+#[const_trait]
+trait B {}
+
+impl const A for S {}
+impl const B for S {}
+
+impl S {
+    const fn a<T: ~const A>() where T: ~const B {
+
+    }
+}
+
+const _: () = S::a::<S>();
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/inherent-impl.rs b/tests/ui/traits/const-traits/inherent-impl.rs
new file mode 100644
index 00000000000..afd0d137bb4
--- /dev/null
+++ b/tests/ui/traits/const-traits/inherent-impl.rs
@@ -0,0 +1,13 @@
+#![feature(const_trait_impl)]
+#![allow(bare_trait_objects)]
+
+struct S;
+trait T {}
+
+impl const S {}
+//~^ ERROR inherent impls cannot be `const`
+
+impl const T {}
+//~^ ERROR inherent impls cannot be `const`
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/inherent-impl.stderr b/tests/ui/traits/const-traits/inherent-impl.stderr
new file mode 100644
index 00000000000..8c55627031d
--- /dev/null
+++ b/tests/ui/traits/const-traits/inherent-impl.stderr
@@ -0,0 +1,22 @@
+error: inherent impls cannot be `const`
+  --> $DIR/inherent-impl.rs:7:12
+   |
+LL | impl const S {}
+   |      ----- ^ inherent impl for this type
+   |      |
+   |      `const` because of this
+   |
+   = note: only trait implementations may be annotated with `const`
+
+error: inherent impls cannot be `const`
+  --> $DIR/inherent-impl.rs:10:12
+   |
+LL | impl const T {}
+   |      ----- ^ inherent impl for this type
+   |      |
+   |      `const` because of this
+   |
+   = note: only trait implementations may be annotated with `const`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs
new file mode 100644
index 00000000000..e3adcce17b4
--- /dev/null
+++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.rs
@@ -0,0 +1,32 @@
+// This test demonstrates an ICE that may occur when we try to resolve the instance
+// of a impl that has different generics than the trait it's implementing. This ensures
+// we first check that the args are compatible before resolving the body, just like
+// we do in projection before substituting a GAT.
+//
+// Const traits aren't the only way to achieve this ICE, but it's a convenient way
+// to ensure the inliner is called.
+
+//@ compile-flags: -Znext-solver -Zinline-mir=yes
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+trait Trait {
+    fn foo(self);
+}
+
+impl Trait for () {
+    #[inline]
+    fn foo<T>(self) {
+        //~^ ERROR  method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+        todo!();
+    }
+}
+
+const fn foo() {
+    ().foo();
+}
+
+const UWU: () = foo();
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr
new file mode 100644
index 00000000000..2e7801c0b8a
--- /dev/null
+++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr
@@ -0,0 +1,21 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:11: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[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:20:12
+   |
+LL |     fn foo(self);
+   |           - expected 0 type parameters
+...
+LL |     fn foo<T>(self) {
+   |            ^ found 1 type parameter
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/const-traits/issue-100222.rs b/tests/ui/traits/const-traits/issue-100222.rs
new file mode 100644
index 00000000000..13c469d656c
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-100222.rs
@@ -0,0 +1,42 @@
+//@ revisions: nn ny yn yy
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects, associated_type_defaults)]
+
+#[cfg_attr(any(yn, yy), const_trait)]
+pub trait Index {
+    type Output;
+}
+
+#[cfg_attr(any(ny, yy), const_trait)]
+pub trait IndexMut where Self: Index {
+    const C: <Self as Index>::Output;
+    type Assoc = <Self as Index>::Output;
+    fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output;
+}
+
+impl Index for () { type Output = (); }
+
+#[cfg(not(any(nn, yn)))]
+impl const IndexMut for <() as Index>::Output {
+    const C: <Self as Index>::Output = ();
+    type Assoc = <Self as Index>::Output;
+    fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
+        where <Self as Index>::Output:,
+    {}
+}
+
+#[cfg(any(nn, yn))]
+impl IndexMut for <() as Index>::Output {
+    const C: <Self as Index>::Output = ();
+    type Assoc = <Self as Index>::Output;
+    fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
+        where <Self as Index>::Output:,
+    {}
+}
+
+const C: <() as Index>::Output = ();
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/issue-102156.rs b/tests/ui/traits/const-traits/issue-102156.rs
new file mode 100644
index 00000000000..fe4e9108130
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-102156.rs
@@ -0,0 +1,15 @@
+#![feature(allocator_api)]
+#![feature(const_trait_impl)]
+
+use core::convert::{From, TryFrom};
+//~^ ERROR
+//~| ERROR
+
+use std::pin::Pin;
+use std::alloc::Allocator;
+impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
+where
+    A: 'static,
+{}
+
+pub fn main() {}
diff --git a/tests/ui/traits/const-traits/issue-102156.stderr b/tests/ui/traits/const-traits/issue-102156.stderr
new file mode 100644
index 00000000000..0c836a614f8
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-102156.stderr
@@ -0,0 +1,23 @@
+error[E0433]: failed to resolve: you might be missing crate `core`
+  --> $DIR/issue-102156.rs:4:5
+   |
+LL | use core::convert::{From, TryFrom};
+   |     ^^^^
+   |     |
+   |     you might be missing crate `core`
+   |     help: try using `std` instead of `core`: `std`
+
+error[E0433]: failed to resolve: you might be missing crate `core`
+  --> $DIR/issue-102156.rs:4:5
+   |
+LL | use core::convert::{From, TryFrom};
+   |     ^^^^
+   |     |
+   |     you might be missing crate `core`
+   |     help: try using `std` instead of `core`: `std`
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/traits/const-traits/issue-102985.rs b/tests/ui/traits/const-traits/issue-102985.rs
new file mode 100644
index 00000000000..e5394ddd688
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-102985.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #110395
+#![feature(const_trait_impl)]
+
+struct Bug {
+    inner: [(); match || 1 {
+        n => n(),
+        //FIXME ~^ ERROR the trait bound
+        //FIXME ~| ERROR the trait bound
+        //FIXME ~| ERROR cannot call non-const closure in constants
+    }],
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/issue-102985.stderr b/tests/ui/traits/const-traits/issue-102985.stderr
new file mode 100644
index 00000000000..8401d1bd4f6
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-102985.stderr
@@ -0,0 +1,16 @@
+error[E0015]: cannot call non-const closure in constants
+  --> $DIR/issue-102985.rs:6:14
+   |
+LL |         n => n(),
+   |              ^^^
+   |
+   = note: closures need an RFC before allowed to be called in constants
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/issue-103677.rs b/tests/ui/traits/const-traits/issue-103677.rs
new file mode 100644
index 00000000000..c032cc7a688
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-103677.rs
@@ -0,0 +1,5 @@
+//@ check-pass
+
+const _: fn(&String) = |s| { &*s as &str; };
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/issue-79450.rs b/tests/ui/traits/const-traits/issue-79450.rs
new file mode 100644
index 00000000000..b8b9e07b3bd
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-79450.rs
@@ -0,0 +1,22 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_fmt_arguments_new)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Tr {
+    fn req(&self);
+
+    fn prov(&self) {
+        println!("lul"); //~ ERROR: cannot call non-const fn `_print` in constant functions
+        self.req();
+    }
+}
+
+struct S;
+
+impl const Tr for S {
+    fn req(&self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr
new file mode 100644
index 00000000000..9e6348d37ed
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-79450.stderr
@@ -0,0 +1,12 @@
+error[E0015]: cannot call non-const fn `_print` in constant functions
+  --> $DIR/issue-79450.rs:11:9
+   |
+LL |         println!("lul");
+   |         ^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/issue-88155.rs b/tests/ui/traits/const-traits/issue-88155.rs
new file mode 100644
index 00000000000..08739de8313
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-88155.rs
@@ -0,0 +1,15 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl)]
+
+pub trait A {
+    fn assoc() -> bool;
+}
+
+pub const fn foo<T: A>() -> bool {
+    T::assoc()
+    //FIXME ~^ ERROR the trait bound
+    //FIXME ~| ERROR cannot call non-const fn
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr
new file mode 100644
index 00000000000..afe1ea3b1b7
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-88155.stderr
@@ -0,0 +1,15 @@
+error[E0015]: cannot call non-const fn `<T as A>::assoc` in constant functions
+  --> $DIR/issue-88155.rs:10:5
+   |
+LL |     T::assoc()
+   |     ^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/issue-92111.rs b/tests/ui/traits/const-traits/issue-92111.rs
new file mode 100644
index 00000000000..64fa32156c3
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-92111.rs
@@ -0,0 +1,24 @@
+// Regression test for #92111.
+//
+//@ known-bug: #110395
+// FIXME check-pass
+
+#![feature(const_trait_impl)]
+
+use std::marker::Destruct;
+
+pub trait Tr {}
+
+#[allow(drop_bounds)]
+impl<T: Drop> Tr for T {}
+
+#[derive(Debug)]
+pub struct S(i32);
+
+impl Tr for S {}
+
+const fn a<T: ~const Destruct>(t: T) {}
+
+fn main() {
+    a(S(0));
+}
diff --git a/tests/ui/traits/const-traits/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr
new file mode 100644
index 00000000000..ecc994a3fe6
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-92111.stderr
@@ -0,0 +1,17 @@
+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) {}
+   |                      ^^^^^^^^
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/issue-92111.rs:20:32
+   |
+LL | const fn a<T: ~const Destruct>(t: T) {}
+   |                                ^      - value is dropped here
+   |                                |
+   |                                the destructor for this type cannot be evaluated in constant functions
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs b/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs
new file mode 100644
index 00000000000..e666355db6f
--- /dev/null
+++ b/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs
@@ -0,0 +1,17 @@
+// Regression test for #92230.
+//
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+#![feature(const_trait_impl, effects)]
+#![allow(incomplete_features)]
+
+#[const_trait]
+pub trait Super {}
+#[const_trait]
+pub trait Sub: Super {}
+
+impl<A> const Super for &A where A: ~const Super {}
+impl<A> const Sub for &A where A: ~const Sub {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr b/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr
new file mode 100644
index 00000000000..c7d21151661
--- /dev/null
+++ b/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr
@@ -0,0 +1,16 @@
+error[E0015]: cannot match on `str` in constant functions
+  --> $DIR/match-non-const-eq.rs:7:9
+   |
+LL |         "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
+   |         ^^^
+   |
+   = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/match-non-const-eq.rs b/tests/ui/traits/const-traits/match-non-const-eq.rs
new file mode 100644
index 00000000000..73f8af86bd0
--- /dev/null
+++ b/tests/ui/traits/const-traits/match-non-const-eq.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #110395
+//@ revisions: stock gated
+#![cfg_attr(gated, feature(const_trait_impl))]
+
+const fn foo(input: &'static str) {
+    match input {
+        "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
+        //FIXME ~^ ERROR cannot match on `str` in constant functions
+        _ => (),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr b/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr
new file mode 100644
index 00000000000..0f5ecac3891
--- /dev/null
+++ b/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr
@@ -0,0 +1,16 @@
+error[E0015]: cannot match on `str` in constant functions
+  --> $DIR/match-non-const-eq.rs:7:9
+   |
+LL |         "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
+   |         ^^^
+   |
+   = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs
new file mode 100644
index 00000000000..820d3d63b62
--- /dev/null
+++ b/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs
@@ -0,0 +1,20 @@
+// Ensure that we don't consider `const Trait` and `~const Trait` to
+// match the macro fragment specifier `ty` as that would be a breaking
+// change theoretically speaking. Syntactically trait object types can
+// be "bare", i.e., lack the prefix `dyn`.
+// By contrast, `?Trait` *does* match `ty` and therefore an arm like
+// `?$Trait:path` would never be reached.
+// See `parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs`.
+
+//@ check-pass
+
+macro_rules! check {
+    ($Type:ty) => { compile_error!("ty"); };
+    (const $Trait:path) => {};
+    (~const $Trait:path) => {};
+}
+
+check! { const Trait }
+check! { ~const Trait }
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs
new file mode 100644
index 00000000000..3dcdb0cad94
--- /dev/null
+++ b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs
@@ -0,0 +1,21 @@
+// Demonstrates and records a theoretical regressions / breaking changes caused by the
+// introduction of const trait bounds.
+
+// Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018.
+//@ edition:2018
+
+macro_rules! demo {
+    ($ty:ty) => { compile_error!("ty"); };
+    //~^ ERROR ty
+    //~| ERROR ty
+    (impl $c:ident Trait) => {};
+    (dyn $c:ident Trait) => {};
+}
+
+demo! { impl const Trait }
+//~^ ERROR const trait impls are experimental
+
+demo! { dyn const Trait }
+//~^ ERROR const trait impls are experimental
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr
new file mode 100644
index 00000000000..f4b401b7386
--- /dev/null
+++ b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr
@@ -0,0 +1,45 @@
+error: ty
+  --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19
+   |
+LL |     ($ty:ty) => { compile_error!("ty"); };
+   |                   ^^^^^^^^^^^^^^^^^^^^
+...
+LL | demo! { impl const Trait }
+   | -------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: ty
+  --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19
+   |
+LL |     ($ty:ty) => { compile_error!("ty"); };
+   |                   ^^^^^^^^^^^^^^^^^^^^
+...
+LL | demo! { dyn const Trait }
+   | ------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:15:14
+   |
+LL | demo! { impl const Trait }
+   |              ^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:18:13
+   |
+LL | demo! { dyn const Trait }
+   |             ^^^^^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs b/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs
new file mode 100644
index 00000000000..9d65a2ac302
--- /dev/null
+++ b/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs
@@ -0,0 +1,13 @@
+// Ensure that the introduction of const trait bound didn't regress this code in Rust 2015.
+// See also `mbe-const-trait-bound-theoretical-regression.rs`.
+
+//@ check-pass
+
+macro_rules! check {
+    ($ty:ty) => { compile_error!("ty"); };
+    (dyn $c:ident) => {};
+}
+
+check! { dyn const }
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs
new file mode 100644
index 00000000000..aaab8e819a3
--- /dev/null
+++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs
@@ -0,0 +1,20 @@
+#![feature(const_trait_impl)]
+
+const fn maybe_const_maybe<T: ~const ?Sized>() {}
+//~^ ERROR `~const` trait not allowed with `?` trait polarity modifier
+
+fn const_maybe<T: const ?Sized>() {}
+//~^ ERROR `const` trait not allowed with `?` trait polarity modifier
+
+const fn maybe_const_negative<T: ~const !Trait>() {}
+//~^ ERROR `~const` trait not allowed with `!` trait polarity modifier
+//~| ERROR negative bounds are not supported
+
+fn const_negative<T: const !Trait>() {}
+//~^ ERROR `const` trait not allowed with `!` trait polarity modifier
+//~| ERROR negative bounds are not supported
+
+#[const_trait]
+trait Trait {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr
new file mode 100644
index 00000000000..18e4d160f5f
--- /dev/null
+++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr
@@ -0,0 +1,46 @@
+error: `~const` trait not allowed with `?` trait polarity modifier
+  --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:38
+   |
+LL | const fn maybe_const_maybe<T: ~const ?Sized>() {}
+   |                               ------ ^
+   |                               |
+   |                               there is not a well-defined meaning for a `~const ?` trait
+
+error: `const` trait not allowed with `?` trait polarity modifier
+  --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:25
+   |
+LL | fn const_maybe<T: const ?Sized>() {}
+   |                   ----- ^
+   |                   |
+   |                   there is not a well-defined meaning for a `const ?` trait
+
+error: `~const` trait not allowed with `!` trait polarity modifier
+  --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41
+   |
+LL | const fn maybe_const_negative<T: ~const !Trait>() {}
+   |                                  ------ ^
+   |                                  |
+   |                                  there is not a well-defined meaning for a `~const !` trait
+
+error: `const` trait not allowed with `!` trait polarity modifier
+  --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28
+   |
+LL | fn const_negative<T: const !Trait>() {}
+   |                      ----- ^
+   |                      |
+   |                      there is not a well-defined meaning for a `const !` trait
+
+error: negative bounds are not supported
+  --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41
+   |
+LL | const fn maybe_const_negative<T: ~const !Trait>() {}
+   |                                         ^
+
+error: negative bounds are not supported
+  --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28
+   |
+LL | fn const_negative<T: const !Trait>() {}
+   |                            ^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/traits/const-traits/nested-closure.rs b/tests/ui/traits/const-traits/nested-closure.rs
new file mode 100644
index 00000000000..7bd372c1695
--- /dev/null
+++ b/tests/ui/traits/const-traits/nested-closure.rs
@@ -0,0 +1,12 @@
+//@ check-pass
+
+#![feature(const_trait_impl)]
+
+use std::sync::LazyLock;
+
+static EXTERN_FLAGS: LazyLock<String> = LazyLock::new(|| {
+    let x = || String::new();
+    x()
+});
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
new file mode 100644
index 00000000000..cd8bb5963ad
--- /dev/null
+++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs
@@ -0,0 +1,15 @@
+#![feature(const_closures, const_trait_impl)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    fn foo(&self);
+}
+
+impl Foo for () {
+    fn foo(&self) {}
+}
+
+fn main() {
+    (const || { (()).foo() })();
+    //~^ ERROR: cannot call non-const fn
+}
diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
new file mode 100644
index 00000000000..c362a1077e3
--- /dev/null
+++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr
@@ -0,0 +1,15 @@
+error[E0015]: cannot call non-const fn `<() as Foo>::foo` in constant functions
+  --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:22
+   |
+LL |     (const || { (()).foo() })();
+   |                      ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs
new file mode 100644
index 00000000000..8f11c8a6e55
--- /dev/null
+++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #110395
+
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Convert<T> {
+    fn to(self) -> T;
+}
+
+impl<A, B> const Convert<B> for A where B: ~const From<A> {
+    fn to(self) -> B {
+        B::from(self)
+    }
+}
+
+const FOO: fn() -> String = || "foo".to();
+
+fn main() {}
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
new file mode 100644
index 00000000000..de4783bdb3f
--- /dev/null
+++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr
@@ -0,0 +1,31 @@
+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> {
+   |                                                   ^^^^^^^
+
+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
+   |
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^ found 1 const parameter
+LL | trait Convert<T> {
+LL |     fn to(self) -> T;
+   |          - expected 0 const parameters
+
+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
+   |
+LL |         B::from(self)
+   |         ^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs
new file mode 100644
index 00000000000..69dcb403aa9
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs
@@ -0,0 +1,56 @@
+// Tests that trait bounds on specializing trait impls must be `~const` if the
+// same bound is present on the default impl and is `~const` there.
+//@ known-bug: #110395
+// FIXME(effects) ^ should error
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {
+    fn bar();
+}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+{
+    default fn bar() {}
+}
+
+impl<T> Bar for T
+where
+    T: Foo, //FIXME ~ ERROR missing `~const` qualifier
+    T: Specialize,
+{
+    fn bar() {}
+}
+
+#[const_trait]
+trait Baz {
+    fn baz();
+}
+
+impl<T> const Baz for T
+where
+    T: ~const Foo,
+{
+    default fn baz() {}
+}
+
+impl<T> const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz`
+where
+    T: Foo,
+    T: Specialize,
+{
+    fn baz() {}
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..7643697874f
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -0,0 +1,41 @@
+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
+   |
+LL | / impl<T> Bar for T
+LL | | where
+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
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs
new file mode 100644
index 00000000000..a48a50b9e5c
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs
@@ -0,0 +1,40 @@
+// Tests that a const default trait impl can be specialized by another const
+// trait impl and that the specializing impl will be used during const-eval.
+
+//@ known-bug: #110395
+// FIXME(effects) run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value<T: ~const Value>() -> u32 {
+    T::value()
+}
+
+impl<T> const Value for T {
+    default fn value() -> u32 {
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+    fn value() -> u32 {
+        42
+    }
+}
+
+const ZERO: u32 = get_value::<()>();
+
+const FORTY_TWO: u32 = get_value::<FortyTwo>();
+
+fn main() {
+    assert_eq!(ZERO, 0);
+    assert_eq!(FORTY_TWO, 42);
+}
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
new file mode 100644
index 00000000000..9b2ae8d739c
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr
@@ -0,0 +1,36 @@
+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
+   |
+LL |     T::value()
+   |     ^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs
new file mode 100644
index 00000000000..40fc3b17ae4
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -0,0 +1,26 @@
+// Tests that specializing trait impls must be at least as const as the default impl.
+
+#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+    fn value() -> u32;
+}
+
+impl<T> const Value for T {
+    default fn value() -> u32 {
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl Value for FortyTwo { //~ ERROR cannot specialize on const impl with non-const impl
+    fn value() -> u32 {
+        println!("You can't do that (constly)");
+        42
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr
new file mode 100644
index 00000000000..c51d169dd33
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr
@@ -0,0 +1,22 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/const-default-impl-non-const-specialized-impl.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: cannot specialize on const impl with non-const impl
+  --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
+   |
+LL | impl Value for FortyTwo {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.rs b/tests/ui/traits/const-traits/specialization/default-keyword.rs
new file mode 100644
index 00000000000..d9ffd237dce
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/default-keyword.rs
@@ -0,0 +1,16 @@
+//@ known-bug: #110395
+// FIXME check-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Foo {
+    fn foo();
+}
+
+impl const Foo for u32 {
+    default fn foo() {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.stderr b/tests/ui/traits/const-traits/specialization/default-keyword.stderr
new file mode 100644
index 00000000000..18a25045f4b
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/default-keyword.stderr
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 00000000000..219e5f3a600
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -0,0 +1,50 @@
+// Tests that `~const` trait bounds can be used to specialize const trait impls.
+
+//@ known-bug: #110395
+// FIXME check-pass
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[const_trait]
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {
+    fn foo();
+}
+
+impl<T> const Foo for T {
+    default fn foo() {}
+}
+
+impl<T> const Foo for T
+where
+    T: ~const Specialize,
+{
+    fn foo() {}
+}
+
+#[const_trait]
+trait Bar {
+    fn bar() {}
+}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+{
+    default fn bar() {}
+}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+    T: ~const Specialize,
+{
+    fn bar() {}
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..ecdc7b930e6
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr
@@ -0,0 +1,43 @@
+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
new file mode 100644
index 00000000000..7514baa2fd5
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -0,0 +1,58 @@
+// Tests that `T: ~const Foo` in a specializing impl is treated as equivalent to
+// `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
+
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+#![feature(const_trait_impl)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {
+    fn bar();
+}
+
+impl<T> Bar for T
+where
+    T: Foo,
+{
+    default fn bar() {}
+}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+    T: Specialize,
+{
+    fn bar() {}
+}
+
+#[const_trait]
+trait Baz {
+    fn baz();
+}
+
+impl<T> const Baz for T
+where
+    T: Foo,
+{
+    default fn baz() {}
+}
+
+impl<T> const Baz for T
+where
+    T: ~const Foo,
+    T: Specialize,
+{
+    fn baz() {}
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..6679bb46537
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr
@@ -0,0 +1,43 @@
+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.rs b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs
new file mode 100644
index 00000000000..912b35095f9
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs
@@ -0,0 +1,39 @@
+// Tests that a non-const default impl can be specialized by a const trait impl,
+// but that the default impl cannot be used in a const context.
+//@ known-bug: #110395
+// FIXME(effects) run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value<T: ~const Value>() -> u32 {
+    T::value()
+}
+
+impl<T> Value for T {
+    default fn value() -> u32 {
+        println!("You can't do that (constly)");
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+    fn value() -> u32 {
+        42
+    }
+}
+
+fn main() {
+    let zero = get_value::<()>();
+    assert_eq!(zero, 0);
+
+    const FORTY_TWO: u32 = get_value::<FortyTwo>();
+    assert_eq!(FORTY_TWO, 42);
+}
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
new file mode 100644
index 00000000000..7f363922947
--- /dev/null
+++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr
@@ -0,0 +1,36 @@
+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
+   |
+LL |     T::value()
+   |     ^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/specializing-constness-2.rs b/tests/ui/traits/const-traits/specializing-constness-2.rs
new file mode 100644
index 00000000000..c1fe42b9751
--- /dev/null
+++ b/tests/ui/traits/const-traits/specializing-constness-2.rs
@@ -0,0 +1,31 @@
+#![feature(const_trait_impl, min_specialization, rustc_attrs)]
+//@ known-bug: #110395
+#[rustc_specialization_trait]
+#[const_trait]
+pub trait Sup {}
+
+impl const Sup for () {}
+
+#[const_trait]
+pub trait A {
+    fn a() -> u32;
+}
+
+impl<T: Default> A for T {
+    default fn a() -> u32 {
+        2
+    }
+}
+
+impl<T: Default + ~const Sup> const A for T {
+    fn a() -> u32 {
+        3
+    }
+}
+
+const fn generic<T: Default>() {
+    <T as A>::a();
+    //FIXME ~^ ERROR: the trait bound `T: ~const Sup` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr
new file mode 100644
index 00000000000..bf273f349b4
--- /dev/null
+++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr
@@ -0,0 +1,36 @@
+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
+   |
+LL |     <T as A>::a();
+   |     ^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+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`.
diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs
new file mode 100644
index 00000000000..4501a218ad7
--- /dev/null
+++ b/tests/ui/traits/const-traits/specializing-constness.rs
@@ -0,0 +1,33 @@
+#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] //~ WARN the feature `effects` is incomplete
+
+#[rustc_specialization_trait]
+#[const_trait]
+pub trait Sup {}
+
+impl const Sup for () {}
+
+#[const_trait]
+pub trait A {
+    fn a() -> u32;
+}
+
+#[const_trait]
+pub trait Spec {}
+
+impl<T: ~const Spec> const A for T {
+    default fn a() -> u32 {
+        2
+    }
+}
+
+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
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr
new file mode 100644
index 00000000000..90721af8e5a
--- /dev/null
+++ b/tests/ui/traits/const-traits/specializing-constness.stderr
@@ -0,0 +1,34 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/specializing-constness.rs:1:30
+   |
+LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)]
+   |                              ^^^^^^^
+   |
+   = 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: cannot specialize on const impl with non-const impl
+  --> $DIR/specializing-constness.rs:23:1
+   |
+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
+
diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.rs b/tests/ui/traits/const-traits/staged-api-user-crate.rs
new file mode 100644
index 00000000000..c4ecb8f67a1
--- /dev/null
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.rs
@@ -0,0 +1,16 @@
+//@ aux-build: staged-api.rs
+extern crate staged_api;
+
+use staged_api::*;
+
+// Const stability has no impact on usage in non-const contexts.
+fn non_const_context() {
+    Unstable::func();
+}
+
+const fn stable_const_context() {
+    Unstable::func();
+    //~^ ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
new file mode 100644
index 00000000000..781191ec97c
--- /dev/null
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
@@ -0,0 +1,15 @@
+error[E0015]: cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
+  --> $DIR/staged-api-user-crate.rs:12:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs
new file mode 100644
index 00000000000..f87e723472a
--- /dev/null
+++ b/tests/ui/traits/const-traits/staged-api.rs
@@ -0,0 +1,63 @@
+//@ revisions: stable unstable
+//@ compile-flags: -Znext-solver
+
+#![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file.
+#![feature(const_trait_impl, effects)]
+#![allow(incomplete_features)]
+#![feature(staged_api)]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+//@ aux-build: staged-api.rs
+extern crate staged_api;
+
+use staged_api::*;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Foo;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(unstable, rustc_const_unstable(feature = "foo", issue = "none"))]
+#[cfg_attr(stable, rustc_const_stable(feature = "foo", since = "1.0.0"))]
+impl const MyTrait for Foo {
+    //[stable]~^ ERROR trait implementations cannot be const stable yet
+    fn func() {}
+}
+
+// Const stability has no impact on usage in non-const contexts.
+fn non_const_context() {
+    Unstable::func();
+    Foo::func();
+}
+
+#[unstable(feature = "none", issue = "none")]
+const fn const_context() {
+    Unstable::func();
+    //[stable]~^ ERROR not yet stable as a const fn
+    Foo::func();
+    //[unstable]~^ ERROR not yet stable as a const fn
+    // ^ fails, because the `foo` feature is not active
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(unstable, rustc_const_unstable(feature = "foo", issue = "none"))]
+pub const fn const_context_not_const_stable() {
+    //[stable]~^ ERROR function has missing const stability attribute
+    Unstable::func();
+    //[stable]~^ ERROR not yet stable as a const fn
+    Foo::func();
+    //[unstable]~^ ERROR not yet stable as a const fn
+    // ^ fails, because the `foo` feature is not active
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "cheese", since = "1.0.0")]
+const fn stable_const_context() {
+    Unstable::func();
+    //~^ ERROR not yet stable as a const fn
+    Foo::func();
+    //[unstable]~^ ERROR not yet stable as a const fn
+    const_context_not_const_stable()
+    //[unstable]~^ ERROR not yet stable as a const fn
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/staged-api.stable.stderr b/tests/ui/traits/const-traits/staged-api.stable.stderr
new file mode 100644
index 00000000000..6c07a253f5b
--- /dev/null
+++ b/tests/ui/traits/const-traits/staged-api.stable.stderr
@@ -0,0 +1,49 @@
+error: trait implementations cannot be const stable yet
+  --> $DIR/staged-api.rs:21:1
+   |
+LL | / impl const MyTrait for Foo {
+LL | |
+LL | |     fn func() {}
+LL | | }
+   | |_^
+   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+
+error: function has missing const stability attribute
+  --> $DIR/staged-api.rs:43:1
+   |
+LL | / pub const fn const_context_not_const_stable() {
+LL | |
+LL | |     Unstable::func();
+LL | |
+...  |
+LL | |     // ^ fails, because the `foo` feature is not active
+LL | | }
+   | |_^
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:34:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:45:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:55:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: const-stable functions can only call other const-stable functions
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/traits/const-traits/staged-api.unstable.stderr b/tests/ui/traits/const-traits/staged-api.unstable.stderr
new file mode 100644
index 00000000000..1c772f13dd5
--- /dev/null
+++ b/tests/ui/traits/const-traits/staged-api.unstable.stderr
@@ -0,0 +1,42 @@
+error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:36:5
+   |
+LL |     Foo::func();
+   |     ^^^^^^^^^^^
+   |
+   = help: add `#![feature(foo)]` to the crate attributes to enable
+
+error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:47:5
+   |
+LL |     Foo::func();
+   |     ^^^^^^^^^^^
+   |
+   = help: add `#![feature(foo)]` to the crate attributes to enable
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:55:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: const-stable functions can only call other const-stable functions
+
+error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:57:5
+   |
+LL |     Foo::func();
+   |     ^^^^^^^^^^^
+   |
+   = help: const-stable functions can only call other const-stable functions
+
+error: `const_context_not_const_stable` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:59:5
+   |
+LL |     const_context_not_const_stable()
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: const-stable functions can only call other const-stable functions
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/traits/const-traits/static-const-trait-bound.rs b/tests/ui/traits/const-traits/static-const-trait-bound.rs
new file mode 100644
index 00000000000..062067f8e85
--- /dev/null
+++ b/tests/ui/traits/const-traits/static-const-trait-bound.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+pub struct S<T, F: FnOnce() -> T = fn() -> T> {
+    f: F,
+    x: Option<T>,
+}
+
+impl<T, F: FnOnce() -> T> S<T, F> {
+    pub const fn new(f: F) -> Self {
+        Self { f, x: None }
+    }
+}
+
+#[derive(Default)]
+pub struct Foo;
+
+static LOCKED_CALLSITES: S<Foo> = S::new(Default::default);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/std-impl-gate.gated.stderr b/tests/ui/traits/const-traits/std-impl-gate.gated.stderr
new file mode 100644
index 00000000000..d761fdce4bf
--- /dev/null
+++ b/tests/ui/traits/const-traits/std-impl-gate.gated.stderr
@@ -0,0 +1,22 @@
+error[E0635]: unknown feature `const_default_impls`
+  --> $DIR/std-impl-gate.rs:6:46
+   |
+LL | #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))]
+   |                                              ^^^^^^^^^^^^^^^^^^^
+
+error[E0015]: cannot call non-const fn `<Vec<usize> as Default>::default` in constant functions
+  --> $DIR/std-impl-gate.rs:13:5
+   |
+LL |     Default::default()
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(effects)]` to the crate attributes to enable
+   |
+LL + #![feature(effects)]
+   |
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0015, E0635.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/std-impl-gate.rs b/tests/ui/traits/const-traits/std-impl-gate.rs
new file mode 100644
index 00000000000..a9e2ff06290
--- /dev/null
+++ b/tests/ui/traits/const-traits/std-impl-gate.rs
@@ -0,0 +1,21 @@
+// This tests feature gates for const impls in the standard library.
+
+//@ revisions: stock gated
+//@[gated] known-bug: #110395
+
+#![cfg_attr(gated, feature(const_trait_impl, const_default_impls))]
+
+fn non_const_context() -> Vec<usize> {
+    Default::default()
+}
+
+const fn const_context() -> Vec<usize> {
+    Default::default()
+    //[stock]~^ ERROR cannot call non-const fn
+}
+
+fn main() {
+    const VAL: Vec<usize> = const_context();
+
+    assert_eq!(VAL, non_const_context());
+}
diff --git a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
new file mode 100644
index 00000000000..b63ea695fc2
--- /dev/null
+++ b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
@@ -0,0 +1,15 @@
+error[E0015]: cannot call non-const fn `<Vec<usize> as Default>::default` in constant functions
+  --> $DIR/std-impl-gate.rs:13:5
+   |
+LL |     Default::default()
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr
new file mode 100644
index 00000000000..48bb1907be2
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr
@@ -0,0 +1,36 @@
+error: `~const` is not allowed here
+  --> $DIR/super-traits-fail-2.rs:12:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^
+   |
+note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+  --> $DIR/super-traits-fail-2.rs:12:1
+   |
+LL | trait Bar: ~const Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:12:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+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 4 previous errors
+
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
new file mode 100644
index 00000000000..029c3b4bde3
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr
@@ -0,0 +1,24 @@
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:12:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+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 3 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
new file mode 100644
index 00000000000..93a6f385e47
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.rs
@@ -0,0 +1,23 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+//@ revisions: yy yn ny nn
+
+#[cfg_attr(any(yy, yn), const_trait)]
+trait Foo {
+    fn a(&self);
+}
+
+#[cfg_attr(any(yy, ny), const_trait)]
+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
+
+const fn foo<T: Bar>(x: &T) {
+    x.a();
+    //[yy,yn]~^ ERROR the trait bound `T: ~const Foo`
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..873c57ec71f
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr
@@ -0,0 +1,34 @@
+error: `~const` is not allowed here
+  --> $DIR/super-traits-fail-2.rs:12:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^
+   |
+note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+  --> $DIR/super-traits-fail-2.rs:12:1
+   |
+LL | trait Bar: ~const Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-2.rs:19:7
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
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
new file mode 100644
index 00000000000..bea3aea2f3a
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-2.rs:19:7
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
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
new file mode 100644
index 00000000000..f40583f0ca5
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr
@@ -0,0 +1,42 @@
+error: `~const` is not allowed here
+  --> $DIR/super-traits-fail-3.rs:14:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^
+   |
+note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+  --> $DIR/super-traits-fail-3.rs:14:1
+   |
+LL | trait Bar: ~const Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:14:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+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: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:20:24
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                        ^^^
+
+error: aborting due to 5 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
new file mode 100644
index 00000000000..3f6dfa7b008
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr
@@ -0,0 +1,24 @@
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:14:19
+   |
+LL | trait Bar: ~const Foo {}
+   |                   ^^^
+
+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 3 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
new file mode 100644
index 00000000000..b5643b11700
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs
@@ -0,0 +1,26 @@
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+//@ revisions: yy yn ny nn
+//@[yy] check-pass
+
+#[cfg_attr(any(yy, yn), const_trait)]
+trait Foo {
+    fn a(&self);
+}
+
+#[cfg_attr(any(yy, ny), const_trait)]
+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
+
+const fn foo<T: ~const Bar>(x: &T) {
+    //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]`
+    x.a();
+    //[yn]~^ ERROR: the trait bound `T: ~const Foo` is not satisfied
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..bbc95948a59
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr
@@ -0,0 +1,40 @@
+error: `~const` is not allowed here
+  --> $DIR/super-traits-fail-3.rs:14:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^
+   |
+note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+  --> $DIR/super-traits-fail-3.rs:14:1
+   |
+LL | trait Bar: ~const Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:20: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`
+   |
+note: required by a bound in `Foo::a`
+  --> $DIR/super-traits-fail-3.rs:8: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: ~const Bar + Foo>(x: &T) {
+   |                            +++++
+
+error: aborting due to 3 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
new file mode 100644
index 00000000000..da41d7fcc72
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail.rs
@@ -0,0 +1,22 @@
+//~ ERROR the trait bound
+//@ compile-flags: -Znext-solver
+
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Foo {
+    fn a(&self);
+}
+#[const_trait]
+trait Bar: ~const Foo {}
+
+struct S;
+impl Foo for S {
+    fn a(&self) {}
+}
+
+impl const Bar for S {}
+//~^ ERROR the trait bound
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr
new file mode 100644
index 00000000000..3870f0f722f
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits-fail.stderr
@@ -0,0 +1,24 @@
+error[E0277]: the trait bound `Bar::{synthetic#0}: TyCompat<Foo::{synthetic#0}>` is not satisfied
+  --> $DIR/super-traits-fail.rs:19:12
+   |
+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
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/super-traits.rs b/tests/ui/traits/const-traits/super-traits.rs
new file mode 100644
index 00000000000..ff7349bba3c
--- /dev/null
+++ b/tests/ui/traits/const-traits/super-traits.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Foo {
+    fn a(&self);
+}
+
+#[const_trait]
+trait Bar: ~const Foo {}
+
+struct S;
+impl const Foo for S {
+    fn a(&self) {}
+}
+
+impl const Bar for S {}
+
+const fn foo<T: ~const Bar>(t: &T) {
+    t.a();
+}
+
+const _: () = foo(&S);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/syntax.rs b/tests/ui/traits/const-traits/syntax.rs
new file mode 100644
index 00000000000..1064713ac59
--- /dev/null
+++ b/tests/ui/traits/const-traits/syntax.rs
@@ -0,0 +1,8 @@
+//@ compile-flags: -Z parse-only
+//@ check-pass
+
+#![feature(const_trait_bound_opt_out)]
+#![feature(const_trait_impl)]
+
+// For now, this parses since an error does not occur until AST lowering.
+impl ~const T {}
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
new file mode 100644
index 00000000000..4b720b534a4
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs
@@ -0,0 +1,37 @@
+#![feature(const_trait_impl, effects)]
+#![feature(generic_arg_infer)]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+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
+    }
+}
+
+#[const_trait]
+trait Add42 {
+    fn add(a: usize) -> usize;
+}
+
+impl const Add42 for () {
+    fn add(a: usize) -> usize {
+        a + 42
+    }
+}
+
+fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
+    //~^ ERROR `~const` is not allowed here
+    //~| ERROR mismatched types
+    Foo
+}
+
+fn main() {
+    let foo = Foo::<0>;
+    let foo = bar::<(), _>(foo);
+    let _foo = bar::<(), _>(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
new file mode 100644
index 00000000000..73526a26e08
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr
@@ -0,0 +1,50 @@
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-and-const-params.rs:9:15
+   |
+LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
+   |               ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-and-const-params.rs:9:8
+   |
+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
+   |
+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
+   |
+LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
+   |    ^^^
+
+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
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs b/tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs
new file mode 100644
index 00000000000..8e7202ecaa1
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs
@@ -0,0 +1,30 @@
+// Regression test for issue #119700.
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Main {
+    fn compute<T: ~const Aux>() -> u32;
+}
+
+impl const Main for () {
+    fn compute<T: ~const Aux>() -> u32 {
+        T::generate()
+    }
+}
+
+#[const_trait]
+trait Aux {
+    fn generate() -> u32;
+}
+
+impl const Aux for () {
+    fn generate() -> u32 { 1024 }
+}
+
+fn main() {
+    const _: u32 = <()>::compute::<()>();
+    let _ = <()>::compute::<()>();
+}
diff --git a/tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs b/tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs
new file mode 100644
index 00000000000..71c5d8366b2
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Foo {
+    fn foo(&self) {}
+}
+
+struct Bar<T>(T);
+
+impl<T> Bar<T> {
+    const fn foo(&self) where T: ~const Foo {
+        self.0.foo()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/tilde-const-invalid-places.rs b/tests/ui/traits/const-traits/tilde-const-invalid-places.rs
new file mode 100644
index 00000000000..9d220686771
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-invalid-places.rs
@@ -0,0 +1,61 @@
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Trait {}
+
+// Regression test for issue #90052.
+fn non_const_function<T: ~const Trait>() {} //~ ERROR `~const` is not allowed
+
+struct Struct<T: ~const Trait> { field: T } //~ ERROR `~const` is not allowed here
+struct TupleStruct<T: ~const Trait>(T); //~ ERROR `~const` is not allowed here
+struct UnitStruct<T: ~const Trait>; //~ ERROR `~const` is not allowed here
+//~^ ERROR  parameter `T` is never used
+
+enum Enum<T: ~const Trait> { Variant(T) } //~ ERROR `~const` is not allowed here
+
+union Union<T: ~const Trait> { field: T } //~ ERROR `~const` is not allowed here
+//~^ ERROR field must implement `Copy`
+
+type Type<T: ~const Trait> = T; //~ ERROR `~const` is not allowed here
+
+const CONSTANT<T: ~const Trait>: () = (); //~ ERROR `~const` is not allowed here
+//~^ ERROR generic const items are experimental
+
+trait NonConstTrait {
+    type Type<T: ~const Trait>: ~const Trait;
+    //~^ ERROR `~const` is not allowed
+    //~| ERROR `~const` is not allowed
+    fn non_const_function<T: ~const Trait>(); //~ ERROR `~const` is not allowed
+    const CONSTANT<T: ~const Trait>: (); //~ ERROR `~const` is not allowed
+    //~^ ERROR generic const items are experimental
+}
+
+impl NonConstTrait for () {
+    type Type<T: ~const Trait> = (); //~ ERROR `~const` is not allowed
+    //~^ ERROR overflow evaluating the requirement `(): Trait`
+    fn non_const_function<T: ~const Trait>() {} //~ ERROR `~const` is not allowed
+    const CONSTANT<T: ~const Trait>: () = (); //~ ERROR `~const` is not allowed
+    //~^ ERROR generic const items are experimental
+}
+
+struct Implementor;
+
+impl Implementor {
+    type Type<T: ~const Trait> = (); //~ ERROR `~const` is not allowed
+    //~^ ERROR inherent associated types are unstable
+    fn non_const_function<T: ~const Trait>() {} //~ ERROR `~const` is not allowed
+    const CONSTANT<T: ~const Trait>: () = (); //~ ERROR `~const` is not allowed
+    //~^ ERROR generic const items are experimental
+}
+
+// non-const traits
+trait Child0: ~const Trait {} //~ ERROR `~const` is not allowed
+trait Child1 where Self: ~const Trait {} //~ ERROR `~const` is not allowed
+
+// non-const impl
+impl<T: ~const Trait> Trait for T {} //~ ERROR `~const` is not allowed
+
+// inherent impl (regression test for issue #117004)
+impl<T: ~const Trait> Struct<T> {} //~ ERROR `~const` is not allowed
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr b/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr
new file mode 100644
index 00000000000..8151b9aaa23
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr
@@ -0,0 +1,310 @@
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:7:26
+   |
+LL | fn non_const_function<T: ~const Trait>() {}
+   |                          ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:7:4
+   |
+LL | fn non_const_function<T: ~const Trait>() {}
+   |    ^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:9:18
+   |
+LL | struct Struct<T: ~const Trait> { field: T }
+   |                  ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:10:23
+   |
+LL | struct TupleStruct<T: ~const Trait>(T);
+   |                       ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:11:22
+   |
+LL | struct UnitStruct<T: ~const Trait>;
+   |                      ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:14:14
+   |
+LL | enum Enum<T: ~const Trait> { Variant(T) }
+   |              ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:16:16
+   |
+LL | union Union<T: ~const Trait> { field: T }
+   |                ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:19:14
+   |
+LL | type Type<T: ~const Trait> = T;
+   |              ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:21:19
+   |
+LL | const CONSTANT<T: ~const Trait>: () = ();
+   |                   ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:25:18
+   |
+LL |     type Type<T: ~const Trait>: ~const Trait;
+   |                  ^^^^^^
+   |
+note: associated types in non-`#[const_trait]` traits cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:25:5
+   |
+LL |     type Type<T: ~const Trait>: ~const Trait;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:25:33
+   |
+LL |     type Type<T: ~const Trait>: ~const Trait;
+   |                                 ^^^^^^
+   |
+note: associated types in non-`#[const_trait]` traits cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:25:5
+   |
+LL |     type Type<T: ~const Trait>: ~const Trait;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:28:30
+   |
+LL |     fn non_const_function<T: ~const Trait>();
+   |                              ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:28:8
+   |
+LL |     fn non_const_function<T: ~const Trait>();
+   |        ^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:29:23
+   |
+LL |     const CONSTANT<T: ~const Trait>: ();
+   |                       ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:34:18
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |                  ^^^^^^
+   |
+note: associated types in non-const impls cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:34:5
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:36:30
+   |
+LL |     fn non_const_function<T: ~const Trait>() {}
+   |                              ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:36:8
+   |
+LL |     fn non_const_function<T: ~const Trait>() {}
+   |        ^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:37:23
+   |
+LL |     const CONSTANT<T: ~const Trait>: () = ();
+   |                       ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:44:18
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |                  ^^^^^^
+   |
+note: inherent associated types cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:44:5
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:46:30
+   |
+LL |     fn non_const_function<T: ~const Trait>() {}
+   |                              ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:46:8
+   |
+LL |     fn non_const_function<T: ~const Trait>() {}
+   |        ^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:47:23
+   |
+LL |     const CONSTANT<T: ~const Trait>: () = ();
+   |                       ^^^^^^
+   |
+   = note: this item cannot have `~const` trait bounds
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:52:15
+   |
+LL | trait Child0: ~const Trait {}
+   |               ^^^^^^
+   |
+note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:52:1
+   |
+LL | trait Child0: ~const Trait {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:53:26
+   |
+LL | trait Child1 where Self: ~const Trait {}
+   |                          ^^^^^^
+   |
+note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:53:1
+   |
+LL | trait Child1 where Self: ~const Trait {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:56:9
+   |
+LL | impl<T: ~const Trait> Trait for T {}
+   |         ^^^^^^
+   |
+note: this impl is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:56:1
+   |
+LL | impl<T: ~const Trait> Trait for T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-invalid-places.rs:59:9
+   |
+LL | impl<T: ~const Trait> Struct<T> {}
+   |         ^^^^^^
+   |
+note: inherent impls cannot have `~const` trait bounds
+  --> $DIR/tilde-const-invalid-places.rs:59:1
+   |
+LL | impl<T: ~const Trait> Struct<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0658]: generic const items are experimental
+  --> $DIR/tilde-const-invalid-places.rs:21:15
+   |
+LL | const CONSTANT<T: ~const Trait>: () = ();
+   |               ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+   = help: add `#![feature(generic_const_items)]` 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[E0658]: generic const items are experimental
+  --> $DIR/tilde-const-invalid-places.rs:29:19
+   |
+LL |     const CONSTANT<T: ~const Trait>: ();
+   |                   ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+   = help: add `#![feature(generic_const_items)]` 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[E0658]: generic const items are experimental
+  --> $DIR/tilde-const-invalid-places.rs:37:19
+   |
+LL |     const CONSTANT<T: ~const Trait>: () = ();
+   |                   ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+   = help: add `#![feature(generic_const_items)]` 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[E0658]: generic const items are experimental
+  --> $DIR/tilde-const-invalid-places.rs:47:19
+   |
+LL |     const CONSTANT<T: ~const Trait>: () = ();
+   |                   ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+   = help: add `#![feature(generic_const_items)]` 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[E0392]: type parameter `T` is never used
+  --> $DIR/tilde-const-invalid-places.rs:11:19
+   |
+LL | struct UnitStruct<T: ~const Trait>;
+   |                   ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/tilde-const-invalid-places.rs:16:32
+   |
+LL | union Union<T: ~const Trait> { field: T }
+   |                                ^^^^^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL | union Union<T: ~const Trait> { field: std::mem::ManuallyDrop<T> }
+   |                                       +++++++++++++++++++++++ +
+
+error[E0275]: overflow evaluating the requirement `(): Trait`
+  --> $DIR/tilde-const-invalid-places.rs:34:34
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |                                  ^^
+   |
+note: required by a bound in `NonConstTrait::Type`
+  --> $DIR/tilde-const-invalid-places.rs:25:33
+   |
+LL |     type Type<T: ~const Trait>: ~const Trait;
+   |                                 ^^^^^^^^^^^^ required by this bound in `NonConstTrait::Type`
+
+error[E0658]: inherent associated types are unstable
+  --> $DIR/tilde-const-invalid-places.rs:44:5
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+   = help: add `#![feature(inherent_associated_types)]` 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: aborting due to 30 previous errors
+
+Some errors have detailed explanations: E0275, E0392, E0658, E0740.
+For more information about an error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/const-traits/tilde-const-syntax.rs b/tests/ui/traits/const-traits/tilde-const-syntax.rs
new file mode 100644
index 00000000000..d65ecae3d06
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-syntax.rs
@@ -0,0 +1,9 @@
+//@ compile-flags: -Z parse-only
+//@ check-pass
+
+#![feature(const_trait_impl)]
+
+struct S<
+    T: for<'a> ~const Tr<'a> + 'static + ~const std::ops::Add,
+    T: for<'a: 'b> ~const m::Trait<'a>,
+>;
diff --git a/tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs b/tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs
new file mode 100644
index 00000000000..254cf2200d8
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-const-trait-assoc-tys.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Trait {
+    // FIXME(effects): `~const` bounds in trait associated types (excluding associated type bounds)
+    // don't look super useful. Should we forbid them again?
+    type Assoc<T: ~const Bound>;
+}
+
+impl const Trait for () {
+    type Assoc<T: ~const Bound> = T;
+}
+
+#[const_trait]
+trait Bound {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/tilde-twice.rs b/tests/ui/traits/const-traits/tilde-twice.rs
new file mode 100644
index 00000000000..c3f9f8e6764
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-twice.rs
@@ -0,0 +1,6 @@
+//@ compile-flags: -Z parse-only
+
+#![feature(const_trait_impl)]
+
+struct S<T: ~const ~const Tr>;
+//~^ ERROR expected identifier, found `~`
diff --git a/tests/ui/traits/const-traits/tilde-twice.stderr b/tests/ui/traits/const-traits/tilde-twice.stderr
new file mode 100644
index 00000000000..a809736a4f8
--- /dev/null
+++ b/tests/ui/traits/const-traits/tilde-twice.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `~`
+  --> $DIR/tilde-twice.rs:5:20
+   |
+LL | struct S<T: ~const ~const Tr>;
+   |                    ^ expected identifier
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.rs b/tests/ui/traits/const-traits/trait-default-body-stability.rs
new file mode 100644
index 00000000000..b36e9535ca1
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-default-body-stability.rs
@@ -0,0 +1,51 @@
+//@ known-bug: #110395
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(staged_api)]
+#![feature(const_trait_impl, effects)]
+#![feature(const_t_try)]
+#![feature(const_try)]
+#![feature(try_trait_v2)]
+
+#![stable(feature = "foo", since = "1.0")]
+
+use std::ops::{ControlFlow, FromResidual, Try};
+
+#[stable(feature = "foo", since = "1.0")]
+pub struct T;
+
+#[stable(feature = "foo", since = "1.0")]
+#[rustc_const_unstable(feature = "const_t_try", issue = "none")]
+impl const Try for T {
+    type Output = T;
+    type Residual = T;
+
+    fn from_output(t: T) -> T {
+        t
+    }
+
+    fn branch(self) -> ControlFlow<T, T> {
+        ControlFlow::Continue(self)
+    }
+}
+
+#[stable(feature = "foo", since = "1.0")]
+#[rustc_const_unstable(feature = "const_t_try", issue = "none")]
+impl const FromResidual for T {
+    fn from_residual(t: T) -> T {
+        t
+    }
+}
+
+#[stable(feature = "foo", since = "1.0")]
+#[const_trait]
+pub trait Tr {
+    #[stable(feature = "foo", since = "1.0")]
+    fn bar() -> T {
+        T?
+        // Should be allowed.
+        // Must enable unstable features to call this trait fn in const contexts.
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.stderr b/tests/ui/traits/const-traits/trait-default-body-stability.stderr
new file mode 100644
index 00000000000..49fbef9aaa2
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-default-body-stability.stderr
@@ -0,0 +1,20 @@
+error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
+  --> $DIR/trait-default-body-stability.rs:19:12
+   |
+LL | impl const Try for T {
+   |            ^^^
+   |
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
+  --> $DIR/trait-default-body-stability.rs:34:12
+   |
+LL | impl const FromResidual for T {
+   |            ^^^^^^^^^^^^
+   |
+   = 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
+
diff --git a/tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs b/tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs
new file mode 100644
index 00000000000..8a901cc60fd
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-method-ptr-in-consts-ice.rs
@@ -0,0 +1,23 @@
+//@ check-pass
+
+struct LazyLock<T> {
+    data: (Option<T>, fn() -> T),
+}
+
+impl<T> LazyLock<T> {
+    pub const fn new(f: fn() -> T) -> LazyLock<T> {
+        LazyLock { data: (None, f) }
+    }
+}
+
+struct A<T = i32>(Option<T>);
+
+impl<T> Default for A<T> {
+    fn default() -> Self {
+        A(None)
+    }
+}
+
+static EMPTY_SET: LazyLock<A<i32>> = LazyLock::new(A::default);
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.rs b/tests/ui/traits/const-traits/trait-where-clause-const.rs
new file mode 100644
index 00000000000..8ca9b7cc7aa
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.rs
@@ -0,0 +1,36 @@
+//@ compile-flags: -Znext-solver
+// Like trait-where-clause.rs, but we are calling from a const context.
+// Checking the validity of traits' where clauses happen at a later stage.
+// (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a
+// test is not enough.
+
+#![feature(const_trait_impl, effects)]
+#![allow(incomplete_features)]
+
+#[const_trait]
+trait Bar {}
+
+#[const_trait]
+trait Foo {
+    fn a();
+    fn b() where Self: ~const Bar;
+    fn c<T: ~const Bar>();
+}
+
+const fn test1<T: ~const Foo + Bar>() {
+    T::a();
+    T::b();
+    //~^ ERROR mismatched types
+    //~| ERROR the trait bound
+    T::c::<T>();
+    //~^ ERROR mismatched types
+    //~| ERROR the trait bound
+}
+
+const fn test2<T: ~const Foo + ~const Bar>() {
+    T::a();
+    T::b();
+    T::c::<T>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
new file mode 100644
index 00000000000..eaa981ec744
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
@@ -0,0 +1,52 @@
+error[E0277]: the trait bound `T: Foo` 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
+   |
+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
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/trait-where-clause-run.rs b/tests/ui/traits/const-traits/trait-where-clause-run.rs
new file mode 100644
index 00000000000..2837c835429
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-where-clause-run.rs
@@ -0,0 +1,43 @@
+//@ run-pass
+//@ compile-flags: -Znext-solver
+
+#![feature(const_trait_impl, effects)]
+#![allow(incomplete_features)]
+
+#[const_trait]
+trait Bar {
+    fn bar() -> u8;
+}
+
+#[const_trait]
+trait Foo {
+    fn foo() -> u8 where Self: ~const Bar {
+        <Self as Bar>::bar() * 6
+    }
+}
+
+struct NonConst;
+struct Const;
+
+impl Bar for NonConst {
+    fn bar() -> u8 {
+        3
+    }
+}
+
+impl Foo for NonConst {}
+
+impl const Bar for Const {
+    fn bar() -> u8 {
+        4
+    }
+}
+
+impl const Foo for Const {}
+
+fn main() {
+    const ANS1: u8 = Const::foo();
+    let ans2 = NonConst::foo();
+
+    assert_eq!(ANS1 + ans2, 42);
+}
diff --git a/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs b/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs
new file mode 100644
index 00000000000..cb5cc924bfd
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Foo {
+    fn bar() where Self: ~const Foo;
+}
+
+struct S;
+
+impl Foo for S {
+    fn bar() {}
+}
+
+fn baz<T: Foo>() {
+    T::bar();
+}
+
+const fn qux<T: ~const Foo>() {
+    T::bar();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/trait-where-clause.rs b/tests/ui/traits/const-traits/trait-where-clause.rs
new file mode 100644
index 00000000000..11f353f3f8a
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-where-clause.rs
@@ -0,0 +1,28 @@
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Bar {}
+
+trait Foo {
+    fn a();
+    fn b() where Self: ~const Bar;
+    //~^ ERROR `~const` is not allowed here
+    fn c<T: ~const Bar>();
+    //~^ ERROR `~const` is not allowed here
+}
+
+fn test1<T: Foo>() {
+    T::a();
+    T::b();
+    //~^ ERROR the trait bound
+    T::c::<T>();
+    //~^ ERROR the trait bound
+}
+
+fn test2<T: Foo + Bar>() {
+    T::a();
+    T::b();
+    T::c::<T>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/trait-where-clause.stderr b/tests/ui/traits/const-traits/trait-where-clause.stderr
new file mode 100644
index 00000000000..abe24b662a2
--- /dev/null
+++ b/tests/ui/traits/const-traits/trait-where-clause.stderr
@@ -0,0 +1,59 @@
+error: `~const` is not allowed here
+  --> $DIR/trait-where-clause.rs:8:24
+   |
+LL |     fn b() where Self: ~const Bar;
+   |                        ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/trait-where-clause.rs:8:8
+   |
+LL |     fn b() where Self: ~const Bar;
+   |        ^
+
+error: `~const` is not allowed here
+  --> $DIR/trait-where-clause.rs:10:13
+   |
+LL |     fn c<T: ~const Bar>();
+   |             ^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/trait-where-clause.rs:10:8
+   |
+LL |     fn c<T: ~const Bar>();
+   |        ^
+
+error[E0277]: the trait bound `T: Bar` is not satisfied
+  --> $DIR/trait-where-clause.rs:16:5
+   |
+LL |     T::b();
+   |     ^ the trait `Bar` is not implemented for `T`
+   |
+note: required by a bound in `Foo::b`
+  --> $DIR/trait-where-clause.rs:8:24
+   |
+LL |     fn b() where Self: ~const Bar;
+   |                        ^^^^^^^^^^ required by this bound in `Foo::b`
+help: consider further restricting this bound
+   |
+LL | fn test1<T: Foo + Bar>() {
+   |                 +++++
+
+error[E0277]: the trait bound `T: Bar` is not satisfied
+  --> $DIR/trait-where-clause.rs:18:12
+   |
+LL |     T::c::<T>();
+   |            ^ the trait `Bar` is not implemented for `T`
+   |
+note: required by a bound in `Foo::c`
+  --> $DIR/trait-where-clause.rs:10:13
+   |
+LL |     fn c<T: ~const Bar>();
+   |             ^^^^^^^^^^ required by this bound in `Foo::c`
+help: consider further restricting this bound
+   |
+LL | fn test1<T: Foo + Bar>() {
+   |                 +++++
+
+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/unsatisfied-const-trait-bound.rs b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs
new file mode 100644
index 00000000000..d336719f52e
--- /dev/null
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs
@@ -0,0 +1,33 @@
+//@ known-bug: unknown
+// Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics.
+//@ compile-flags: -Znext-solver
+
+#![feature(const_trait_impl, effects, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn require<T: const Trait>() {}
+
+#[const_trait]
+trait Trait {
+    fn make() -> u32;
+}
+
+struct Ty;
+
+impl Trait for Ty {
+    fn make() -> u32 { 0 }
+}
+
+fn main() {
+    require::<Ty>();
+}
+
+struct Container<const N: u32>;
+
+// FIXME(effects): Somehow emit `the trait bound `T: const Trait` is not satisfied` here instead
+//                 and suggest changing `Trait` to `const Trait`.
+fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+
+// FIXME(effects): Instead of suggesting `+ const Trait`, suggest
+//                 changing `~const Trait` to `const Trait`.
+const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
new file mode 100644
index 00000000000..848aa68689b
--- /dev/null
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
@@ -0,0 +1,46 @@
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/unsatisfied-const-trait-bound.rs:5:39
+   |
+LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
+   |                                       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
+error[E0308]: mismatched types
+  --> $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
+  --> $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
+   |
+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`.