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

src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: can't drop `NonTrivialDrop` in const contexts
2-
--> $DIR/const-drop-fail.rs:43:5
2+
--> $DIR/const-drop-fail.rs:44:5
33
|
44
LL | const _: () = check($exp);
55
| ----- required by a bound introduced by this call
@@ -9,7 +9,7 @@ LL | NonTrivialDrop,
99
|
1010
= note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
1111
note: required by a bound in `check`
12-
--> $DIR/const-drop-fail.rs:34:19
12+
--> $DIR/const-drop-fail.rs:35:19
1313
|
1414
LL | const fn check<T: ~const Destruct>(_: T) {}
1515
| ^^^^^^^^^^^^^^^ required by this bound in `check`
@@ -21,7 +21,7 @@ LL | &mut NonTrivialDrop,
2121
| ++++
2222

2323
error[E0277]: can't drop `NonTrivialDrop` in const contexts
24-
--> $DIR/const-drop-fail.rs:45:5
24+
--> $DIR/const-drop-fail.rs:46:5
2525
|
2626
LL | const _: () = check($exp);
2727
| ----- required by a bound introduced by this call
@@ -30,7 +30,7 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
3131
|
3232
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
33-
--> $DIR/const-drop-fail.rs:45:5
33+
--> $DIR/const-drop-fail.rs:46:5
3434
|
3535
LL | ConstImplWithDropGlue(NonTrivialDrop),
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue`
4040
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
4141
| ^^^^^^^^^^^^^^^^^^^^^
4242
note: required by a bound in `check`
43-
--> $DIR/const-drop-fail.rs:34:19
43+
--> $DIR/const-drop-fail.rs:35:19
4444
|
4545
LL | const fn check<T: ~const Destruct>(_: T) {}
4646
| ^^^^^^^^^^^^^^^ required by this bound in `check`
4747

4848
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
49-
--> $DIR/const-drop-fail.rs:47:5
49+
--> $DIR/const-drop-fail.rs:48:5
5050
|
5151
LL | const _: () = check($exp);
5252
| ----- required by a bound introduced by this call
@@ -55,14 +55,14 @@ LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
5555
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
5656
|
5757
note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
58-
--> $DIR/const-drop-fail.rs:28:25
58+
--> $DIR/const-drop-fail.rs:29:25
5959
|
6060
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
6161
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
6262
= note: 1 redundant requirement hidden
6363
= note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
6464
note: required by a bound in `check`
65-
--> $DIR/const-drop-fail.rs:34:19
65+
--> $DIR/const-drop-fail.rs:35:19
6666
|
6767
LL | const fn check<T: ~const Destruct>(_: T) {}
6868
| ^^^^^^^^^^^^^^^ required by this bound in `check`

src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ impl const Drop for ConstImplWithDropGlue {
1919
fn drop(&mut self) {}
2020
}
2121

22-
trait A { fn a() { println!("A"); } }
22+
#[const_trait]
23+
trait A { fn a() { } }
2324

2425
impl A for NonTrivialDrop {}
2526

src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: can't drop `NonTrivialDrop` in const contexts
2-
--> $DIR/const-drop-fail.rs:43:5
2+
--> $DIR/const-drop-fail.rs:44:5
33
|
44
LL | const _: () = check($exp);
55
| ----- required by a bound introduced by this call
@@ -9,7 +9,7 @@ LL | NonTrivialDrop,
99
|
1010
= note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
1111
note: required by a bound in `check`
12-
--> $DIR/const-drop-fail.rs:34:19
12+
--> $DIR/const-drop-fail.rs:35:19
1313
|
1414
LL | const fn check<T: ~const Destruct>(_: T) {}
1515
| ^^^^^^^^^^^^^^^ required by this bound in `check`
@@ -21,7 +21,7 @@ LL | &mut NonTrivialDrop,
2121
| ++++
2222

2323
error[E0277]: can't drop `NonTrivialDrop` in const contexts
24-
--> $DIR/const-drop-fail.rs:45:5
24+
--> $DIR/const-drop-fail.rs:46:5
2525
|
2626
LL | const _: () = check($exp);
2727
| ----- required by a bound introduced by this call
@@ -30,7 +30,7 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
3131
|
3232
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
33-
--> $DIR/const-drop-fail.rs:45:5
33+
--> $DIR/const-drop-fail.rs:46:5
3434
|
3535
LL | ConstImplWithDropGlue(NonTrivialDrop),
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue`
4040
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
4141
| ^^^^^^^^^^^^^^^^^^^^^
4242
note: required by a bound in `check`
43-
--> $DIR/const-drop-fail.rs:34:19
43+
--> $DIR/const-drop-fail.rs:35:19
4444
|
4545
LL | const fn check<T: ~const Destruct>(_: T) {}
4646
| ^^^^^^^^^^^^^^^ required by this bound in `check`
4747

4848
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
49-
--> $DIR/const-drop-fail.rs:47:5
49+
--> $DIR/const-drop-fail.rs:48:5
5050
|
5151
LL | const _: () = check($exp);
5252
| ----- required by a bound introduced by this call
@@ -55,14 +55,14 @@ LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
5555
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
5656
|
5757
note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
58-
--> $DIR/const-drop-fail.rs:28:25
58+
--> $DIR/const-drop-fail.rs:29:25
5959
|
6060
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
6161
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
6262
= note: 1 redundant requirement hidden
6363
= note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
6464
note: required by a bound in `check`
65-
--> $DIR/const-drop-fail.rs:34:19
65+
--> $DIR/const-drop-fail.rs:35:19
6666
|
6767
LL | const fn check<T: ~const Destruct>(_: T) {}
6868
| ^^^^^^^^^^^^^^^ required by this bound in `check`

src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ pub trait A {}
55

66
impl const A for () {}
77
//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]`
8+
//~| ERROR: ~const can only be applied to `#[const_trait]` traits
89

910
fn main() {}

src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ note: this trait must be annotated with `#[const_trait]`
1010
LL | pub trait A {}
1111
| ^^^^^^^^^^^
1212

13-
error: aborting due to previous error
13+
error: ~const can only be applied to `#[const_trait]` traits
14+
--> $DIR/const-impl-requires-const-trait.rs:6:12
15+
|
16+
LL | impl const A for () {}
17+
| ^
18+
19+
error: aborting due to 2 previous errors
1420

src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(const_trait_impl)]
22

3+
#[const_trait]
34
trait Tr {}
45
impl Tr for () {}
56

src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
2-
--> $DIR/default-method-body-is-const-body-checking.rs:11:15
2+
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
33
|
44
LL | foo::<()>();
55
| ^^ the trait `~const Tr` is not implemented for `()`
66
|
77
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
8-
--> $DIR/default-method-body-is-const-body-checking.rs:11:15
8+
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
99
|
1010
LL | foo::<()>();
1111
| ^^
1212
note: required by a bound in `foo`
13-
--> $DIR/default-method-body-is-const-body-checking.rs:6:28
13+
--> $DIR/default-method-body-is-const-body-checking.rs:7:28
1414
|
1515
LL | const fn foo<T>() where T: ~const Tr {}
1616
| ^^^^^^^^^ required by this bound in `foo`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/super-traits-fail-2.rs:11:12
3+
|
4+
LL | trait Bar: ~const Foo {}
5+
| ^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/super-traits-fail-2.rs:11:12
3+
|
4+
LL | trait Bar: ~const Foo {}
5+
| ^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
#![feature(const_trait_impl)]
22

3+
// revisions: yy yn ny nn
4+
5+
#[cfg_attr(any(yy, yn), const_trait)]
36
trait Foo {
47
fn a(&self);
58
}
9+
10+
#[cfg_attr(any(yy, ny), const_trait)]
611
trait Bar: ~const Foo {}
12+
//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
713

814
const fn foo<T: Bar>(x: &T) {
915
x.a();
10-
//~^ ERROR the trait bound
11-
//~| ERROR cannot call
16+
//[yn,yy]~^ ERROR the trait bound
1217
}
1318

1419
fn main() {}

src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)