Skip to content

Commit 33bcea8

Browse files
committed
Only allow ~const bounds for traits with #[const_trait]
1 parent d9f8b4b commit 33bcea8

34 files changed

+192
-83
lines changed

compiler/rustc_trait_selection/src/traits/wf.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ impl<'tcx> WfPredicates<'tcx> {
308308
let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
309309
self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs)
310310
} else {
311+
if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) {
312+
tcx.sess
313+
.span_err(self.span, "~const can only be applied to `#[const_trait]` traits");
314+
}
311315
self.nominal_obligations(trait_ref.def_id, trait_ref.substs)
312316
};
313317

library/core/src/iter/traits/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub trait IntoIterator {
264264

265265
#[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")]
266266
#[stable(feature = "rust1", since = "1.0.0")]
267-
impl<I: ~const Iterator> const IntoIterator for I {
267+
impl<I: Iterator> const IntoIterator for I {
268268
type Item = I::Item;
269269
type IntoIter = I;
270270

library/core/src/marker.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,7 @@ impl<T: ?Sized> Unpin for *mut T {}
799799
#[unstable(feature = "const_trait_impl", issue = "67792")]
800800
#[lang = "destruct"]
801801
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
802+
#[const_trait]
802803
pub trait Destruct {}
803804

804805
/// A marker for tuple types.

src/test/ui/consts/const-fn-error.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ LL | for i in 0..x {
2222
note: impl defined here, but it is not `const`
2323
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
2424
|
25-
LL | impl<I: ~const Iterator> const IntoIterator for I {
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
LL | impl<I: Iterator> const IntoIterator for I {
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
2828

2929
error[E0658]: mutable references are not allowed in constant functions

src/test/ui/consts/const-for.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | for _ in 0..5 {}
77
note: impl defined here, but it is not `const`
88
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
99
|
10-
LL | impl<I: ~const Iterator> const IntoIterator for I {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10+
LL | impl<I: Iterator> const IntoIterator for I {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
1313

1414
error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants

src/test/ui/consts/constifconst-call-in-const-position.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#![feature(const_trait_impl, generic_const_exprs)]
44

5+
#[const_trait]
56
pub trait Tr {
67
fn a() -> usize;
78
}

src/test/ui/consts/constifconst-call-in-const-position.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
88
= note: `#[warn(incomplete_features)]` on by default
99

1010
error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
11-
--> $DIR/constifconst-call-in-const-position.rs:15:38
11+
--> $DIR/constifconst-call-in-const-position.rs:16:38
1212
|
1313
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
1414
| ^^^^^^ calling non-const function `<() as Tr>::a`

src/test/ui/never_type/issue-52443.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ LL | [(); { for _ in 0usize.. {}; 0}];
4747
note: impl defined here, but it is not `const`
4848
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
4949
|
50-
LL | impl<I: ~const Iterator> const IntoIterator for I {
51-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50+
LL | impl<I: Iterator> const IntoIterator for I {
51+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5252
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
5353

5454
error[E0658]: mutable references are not allowed in constants

src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22

33
struct S;
44

5-
impl PartialEq for S {
5+
#[const_trait]
6+
trait Foo {
7+
fn eq(&self, _: &Self) -> bool;
8+
}
9+
10+
impl Foo for S {
611
fn eq(&self, _: &S) -> bool {
712
true
813
}
914
}
1015

11-
const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
16+
const fn equals_self<T: ~const Foo>(t: &T) -> bool {
1217
true
1318
}
1419

src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
1-
error[E0277]: can't compare `S` with `S` in const contexts
2-
--> $DIR/call-generic-method-nonconst.rs:18:34
1+
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
2+
--> $DIR/call-generic-method-nonconst.rs:23:34
33
|
44
LL | pub const EQ: bool = equals_self(&S);
5-
| ----------- ^^ no implementation for `S == S`
5+
| ----------- ^^ the trait `~const Foo` is not implemented for `S`
66
| |
77
| required by a bound introduced by this call
88
|
9-
= help: the trait `~const PartialEq` is not implemented for `S`
10-
note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
11-
--> $DIR/call-generic-method-nonconst.rs:18:34
9+
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
10+
--> $DIR/call-generic-method-nonconst.rs:23:34
1211
|
1312
LL | pub const EQ: bool = equals_self(&S);
1413
| ^^
1514
note: required by a bound in `equals_self`
16-
--> $DIR/call-generic-method-nonconst.rs:11:25
17-
|
18-
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
19-
| ^^^^^^^^^^^^^^^^ required by this bound in `equals_self`
20-
help: consider annotating `S` with `#[derive(PartialEq)]`
21-
|
22-
LL | #[derive(PartialEq)]
15+
--> $DIR/call-generic-method-nonconst.rs:16:25
2316
|
17+
LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
18+
| ^^^^^^^^^^ required by this bound in `equals_self`
2419

2520
error: aborting due to previous error
2621

0 commit comments

Comments
 (0)