about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-10-03 17:08:42 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-10-04 08:06:54 +0000
commit33bcea8f614f5019012f16b49dc3cd934326ca87 (patch)
treeb47a72a2d9195bc4d203a1f52c0638a6c15a7fce
parentd9f8b4b98503e3f88623eb59d4f20432161b840a (diff)
downloadrust-33bcea8f614f5019012f16b49dc3cd934326ca87.tar.gz
rust-33bcea8f614f5019012f16b49dc3cd934326ca87.zip
Only allow ~const bounds for traits with #[const_trait]
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs4
-rw-r--r--library/core/src/iter/traits/collect.rs2
-rw-r--r--library/core/src/marker.rs1
-rw-r--r--src/test/ui/consts/const-fn-error.stderr4
-rw-r--r--src/test/ui/consts/const-for.stderr4
-rw-r--r--src/test/ui/consts/constifconst-call-in-const-position.rs1
-rw-r--r--src/test/ui/consts/constifconst-call-in-const-position.stderr2
-rw-r--r--src/test/ui/never_type/issue-52443.stderr4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs9
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr16
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr16
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs9
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr24
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr14
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs20
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr8
34 files changed, 192 insertions, 83 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 9722b48a68a..ef7b27e408c 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -308,6 +308,10 @@ impl<'tcx> WfPredicates<'tcx> {
         let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
             self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs)
         } else {
+            if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) {
+                tcx.sess
+                    .span_err(self.span, "~const can only be applied to `#[const_trait]` traits");
+            }
             self.nominal_obligations(trait_ref.def_id, trait_ref.substs)
         };
 
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index e598a54b4f1..e099700e3e7 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -264,7 +264,7 @@ pub trait IntoIterator {
 
 #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: ~const Iterator> const IntoIterator for I {
+impl<I: Iterator> const IntoIterator for I {
     type Item = I::Item;
     type IntoIter = I;
 
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5cb5e4458cc..d5ed52124e2 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -799,6 +799,7 @@ impl<T: ?Sized> Unpin for *mut T {}
 #[unstable(feature = "const_trait_impl", issue = "67792")]
 #[lang = "destruct"]
 #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
+#[const_trait]
 pub trait Destruct {}
 
 /// A marker for tuple types.
diff --git a/src/test/ui/consts/const-fn-error.stderr b/src/test/ui/consts/const-fn-error.stderr
index e36324f0b3e..02960b363e7 100644
--- a/src/test/ui/consts/const-fn-error.stderr
+++ b/src/test/ui/consts/const-fn-error.stderr
@@ -22,8 +22,8 @@ LL |     for i in 0..x {
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
-LL | impl<I: ~const Iterator> const IntoIterator for I {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<I: Iterator> const IntoIterator for I {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error[E0658]: mutable references are not allowed in constant functions
diff --git a/src/test/ui/consts/const-for.stderr b/src/test/ui/consts/const-for.stderr
index f2e1c8a4991..11e4ae309c0 100644
--- a/src/test/ui/consts/const-for.stderr
+++ b/src/test/ui/consts/const-for.stderr
@@ -7,8 +7,8 @@ LL |     for _ in 0..5 {}
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
-LL | impl<I: ~const Iterator> const IntoIterator for I {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<I: Iterator> const IntoIterator for I {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
diff --git a/src/test/ui/consts/constifconst-call-in-const-position.rs b/src/test/ui/consts/constifconst-call-in-const-position.rs
index bf67e5a3f76..fcf01d5bc71 100644
--- a/src/test/ui/consts/constifconst-call-in-const-position.rs
+++ b/src/test/ui/consts/constifconst-call-in-const-position.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl, generic_const_exprs)]
 
+#[const_trait]
 pub trait Tr {
     fn a() -> usize;
 }
diff --git a/src/test/ui/consts/constifconst-call-in-const-position.stderr b/src/test/ui/consts/constifconst-call-in-const-position.stderr
index e3f67b44678..d4a445120a2 100644
--- a/src/test/ui/consts/constifconst-call-in-const-position.stderr
+++ b/src/test/ui/consts/constifconst-call-in-const-position.stderr
@@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
-  --> $DIR/constifconst-call-in-const-position.rs:15:38
+  --> $DIR/constifconst-call-in-const-position.rs:16:38
    |
 LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
    |                                      ^^^^^^ calling non-const function `<() as Tr>::a`
diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr
index 3c0daa4c55f..0910e9ad77a 100644
--- a/src/test/ui/never_type/issue-52443.stderr
+++ b/src/test/ui/never_type/issue-52443.stderr
@@ -47,8 +47,8 @@ LL |     [(); { for _ in 0usize.. {}; 0}];
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
-LL | impl<I: ~const Iterator> const IntoIterator for I {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<I: Iterator> const IntoIterator for I {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error[E0658]: mutable references are not allowed in constants
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
index d3e14a53a2f..414a8c87d2c 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
@@ -2,13 +2,18 @@
 
 struct S;
 
-impl PartialEq for 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 PartialEq>(t: &T) -> bool {
+const fn equals_self<T: ~const Foo>(t: &T) -> bool {
     true
 }
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
index 0a2a5f0f245..706f5234365 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
@@ -1,26 +1,21 @@
-error[E0277]: can't compare `S` with `S` in const contexts
-  --> $DIR/call-generic-method-nonconst.rs:18:34
+error[E0277]: the trait bound `S: ~const Foo` is not satisfied
+  --> $DIR/call-generic-method-nonconst.rs:23:34
    |
 LL | pub const EQ: bool = equals_self(&S);
-   |                      ----------- ^^ no implementation for `S == S`
+   |                      ----------- ^^ the trait `~const Foo` is not implemented for `S`
    |                      |
    |                      required by a bound introduced by this call
    |
-   = help: the trait `~const PartialEq` is not implemented for `S`
-note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
-  --> $DIR/call-generic-method-nonconst.rs:18:34
+note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
+  --> $DIR/call-generic-method-nonconst.rs:23:34
    |
 LL | pub const EQ: bool = equals_self(&S);
    |                                  ^^
 note: required by a bound in `equals_self`
-  --> $DIR/call-generic-method-nonconst.rs:11:25
-   |
-LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
-   |                         ^^^^^^^^^^^^^^^^ required by this bound in `equals_self`
-help: consider annotating `S` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
+  --> $DIR/call-generic-method-nonconst.rs:16:25
    |
+LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
+   |                         ^^^^^^^^^^ required by this bound in `equals_self`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index 2295a822fa4..ddf0e2d91c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:43:5
+  --> $DIR/const-drop-fail.rs:44:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -9,7 +9,7 @@ LL |     NonTrivialDrop,
    |
    = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
@@ -21,7 +21,7 @@ LL |     &mut NonTrivialDrop,
    |     ++++
 
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -30,7 +30,7 @@ LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
    |
 note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue`
 LL | struct ConstImplWithDropGlue(NonTrivialDrop);
    |        ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
-  --> $DIR/const-drop-fail.rs:47:5
+  --> $DIR/const-drop-fail.rs:48:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -55,14 +55,14 @@ LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
    |
 note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
-  --> $DIR/const-drop-fail.rs:28:25
+  --> $DIR/const-drop-fail.rs:29:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
    |                         ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
index 001dd430a86..565e2c77ac5 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
@@ -19,7 +19,8 @@ impl const Drop for ConstImplWithDropGlue {
     fn drop(&mut self) {}
 }
 
-trait A { fn a() { println!("A"); } }
+#[const_trait]
+trait A { fn a() { } }
 
 impl A for NonTrivialDrop {}
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index 2295a822fa4..ddf0e2d91c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:43:5
+  --> $DIR/const-drop-fail.rs:44:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -9,7 +9,7 @@ LL |     NonTrivialDrop,
    |
    = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
@@ -21,7 +21,7 @@ LL |     &mut NonTrivialDrop,
    |     ++++
 
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -30,7 +30,7 @@ LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
    |
 note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue`
 LL | struct ConstImplWithDropGlue(NonTrivialDrop);
    |        ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
-  --> $DIR/const-drop-fail.rs:47:5
+  --> $DIR/const-drop-fail.rs:48:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -55,14 +55,14 @@ LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
    |
 note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
-  --> $DIR/const-drop-fail.rs:28:25
+  --> $DIR/const-drop-fail.rs:29:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
    |                         ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
index 1aff0562785..8757d74082e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
@@ -5,5 +5,6 @@ pub trait A {}
 
 impl const A for () {}
 //~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]`
+//~| ERROR: ~const can only be applied to `#[const_trait]` traits
 
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
index 6b465a9c62e..f9c69d6c6bf 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
@@ -10,5 +10,11 @@ note: this trait must be annotated with `#[const_trait]`
 LL | pub trait A {}
    | ^^^^^^^^^^^
 
-error: aborting due to previous error
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/const-impl-requires-const-trait.rs:6:12
+   |
+LL | impl const A for () {}
+   |            ^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
index d27291231fb..96acdc300e0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
@@ -1,5 +1,6 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Tr {}
 impl Tr for () {}
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
index 7542b81fe2a..d102956cd2e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
@@ -1,16 +1,16 @@
 error[E0277]: the trait bound `(): ~const Tr` is not satisfied
-  --> $DIR/default-method-body-is-const-body-checking.rs:11:15
+  --> $DIR/default-method-body-is-const-body-checking.rs:12:15
    |
 LL |         foo::<()>();
    |               ^^ the trait `~const Tr` is not implemented for `()`
    |
 note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
-  --> $DIR/default-method-body-is-const-body-checking.rs:11:15
+  --> $DIR/default-method-body-is-const-body-checking.rs:12:15
    |
 LL |         foo::<()>();
    |               ^^
 note: required by a bound in `foo`
-  --> $DIR/default-method-body-is-const-body-checking.rs:6:28
+  --> $DIR/default-method-body-is-const-body-checking.rs:7:28
    |
 LL | const fn foo<T>() where T: ~const Tr {}
    |                            ^^^^^^^^^ required by this bound in `foo`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
new file mode 100644
index 00000000000..b86acb2cc9a
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:11:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
new file mode 100644
index 00000000000..b86acb2cc9a
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:11:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
index 7b38c15afc2..d183efde2df 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
@@ -1,14 +1,19 @@
 #![feature(const_trait_impl)]
 
+// 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]`
 
 const fn foo<T: Bar>(x: &T) {
     x.a();
-    //~^ ERROR the trait bound
-    //~| ERROR cannot call
+    //[yn,yy]~^ ERROR the trait bound
 }
 
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr
deleted file mode 100644
index 1766cdbee8a..00000000000
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-2.rs:9:7
-   |
-LL |     x.a();
-   |       ^^^ the trait `~const Foo` is not implemented for `T`
-   |
-note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/super-traits-fail-2.rs:9:7
-   |
-LL |     x.a();
-   |       ^^^
-
-error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
-  --> $DIR/super-traits-fail-2.rs:9:7
-   |
-LL |     x.a();
-   |       ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0015, E0277.
-For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
new file mode 100644
index 00000000000..b52eb2c0332
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^ - required by a bound introduced by this call
+   |     |
+   |     the trait `~const Foo` is not implemented for `T`
+   |
+note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^
+help: consider further restricting this bound
+   |
+LL | const fn foo<T: Bar + ~const Foo>(x: &T) {
+   |                     ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
new file mode 100644
index 00000000000..b52eb2c0332
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^ - required by a bound introduced by this call
+   |     |
+   |     the trait `~const Foo` is not implemented for `T`
+   |
+note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^
+help: consider further restricting this bound
+   |
+LL | const fn foo<T: Bar + ~const Foo>(x: &T) {
+   |                     ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
new file mode 100644
index 00000000000..191edca1761
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
@@ -0,0 +1,14 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:12:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:15:17
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                 ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
new file mode 100644
index 00000000000..a3b4c302a57
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:12:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
new file mode 100644
index 00000000000..70d2936d3b2
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
@@ -0,0 +1,20 @@
+#![feature(const_trait_impl)]
+
+// 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]`
+
+const fn foo<T: ~const Bar>(x: &T) {
+    //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
+    x.a();
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
new file mode 100644
index 00000000000..9d611665465
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:15:17
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                 ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
index 350be4d8250..5bd52151f42 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
@@ -1,6 +1,7 @@
 #![feature(const_trait_impl)]
 #![feature(associated_type_bounds)]
 
+#[const_trait]
 trait T {}
 struct S;
 impl T for S {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
index 8d781d063d1..5d213315634 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
@@ -1,5 +1,5 @@
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:8:19
+  --> $DIR/tilde-const-invalid-places.rs:9:19
    |
 LL | fn rpit() -> impl ~const T { S }
    |                   ^^^^^^^^
@@ -7,7 +7,7 @@ LL | fn rpit() -> impl ~const T { S }
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:11:17
+  --> $DIR/tilde-const-invalid-places.rs:12:17
    |
 LL | fn apit(_: impl ~const T) {}
    |                 ^^^^^^^^
@@ -15,7 +15,7 @@ LL | fn apit(_: impl ~const T) {}
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:14:50
+  --> $DIR/tilde-const-invalid-places.rs:15:50
    |
 LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
    |                                                  ^^^^^^^^
@@ -23,7 +23,7 @@ LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:17:48
+  --> $DIR/tilde-const-invalid-places.rs:18:48
    |
 LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
    |                                                ^^^^^^^^
@@ -31,7 +31,7 @@ LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` and `?` are mutually exclusive
-  --> $DIR/tilde-const-invalid-places.rs:20:25
+  --> $DIR/tilde-const-invalid-places.rs:21:25
    |
 LL | struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>);
    |                         ^^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
index 47c38c979c3..bfe98b98c74 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
@@ -4,8 +4,10 @@
 // test is not enough.
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Bar {}
 
+#[const_trait]
 trait Foo {
     fn a();
     fn b() where Self: ~const Bar;
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
index 13d8639de30..f2846b6a662 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
-  --> $DIR/trait-where-clause-const.rs:17:5
+  --> $DIR/trait-where-clause-const.rs:19:5
    |
 LL |     T::b();
    |     ^^^^^^ the trait `~const Bar` is not implemented for `T`
    |
 note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/trait-where-clause-const.rs:17:5
+  --> $DIR/trait-where-clause-const.rs:19:5
    |
 LL |     T::b();
    |     ^^^^^^
@@ -15,13 +15,13 @@ LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
    |                                    ++++++++++++
 
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
-  --> $DIR/trait-where-clause-const.rs:19:5
+  --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::c::<T>();
    |     ^^^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
    |
 note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/trait-where-clause-const.rs:19:5
+  --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::c::<T>();
    |     ^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
index acea58eaecb..3b028ac48db 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Foo {
     fn bar() where Self: ~const Foo;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
index 5bd23a8cb20..85ca5fc9048 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
@@ -1,5 +1,6 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Bar {}
 
 trait Foo {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 96365d33433..11f0c40160d 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:13:5
+  --> $DIR/trait-where-clause.rs:14: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:7:24
+  --> $DIR/trait-where-clause.rs:8:24
    |
 LL |     fn b() where Self: ~const Bar;
    |                        ^^^^^^^^^^ required by this bound in `Foo::b`
@@ -15,13 +15,13 @@ LL | fn test1<T: Foo + Bar>() {
    |                 +++++
 
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:15:12
+  --> $DIR/trait-where-clause.rs:16: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:8:13
+  --> $DIR/trait-where-clause.rs:9:13
    |
 LL |     fn c<T: ~const Bar>();
    |             ^^^^^^^^^^ required by this bound in `Foo::c`