Skip to content

Commit d6cf893

Browse files
committed
Require Drop impls to have the same constness on its bounds as the bounds on the struct have
1 parent 349ba6b commit d6cf893

File tree

6 files changed

+116
-53
lines changed

6 files changed

+116
-53
lines changed

compiler/rustc_hir_analysis/src/check/dropck.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
184184
let p = p.kind();
185185
match (predicate.skip_binder(), p.skip_binder()) {
186186
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => {
187-
// Since struct predicates cannot have ~const, project the impl predicate
188-
// onto one that ignores the constness. This is equivalent to saying that
189-
// we match a `Trait` bound on the struct with a `Trait` or `~const Trait`
190-
// in the impl.
191-
let non_const_a =
192-
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..a };
193-
relator.relate(predicate.rebind(non_const_a), p.rebind(b)).is_ok()
187+
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
194188
}
195189
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
196190
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()

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

+43-22
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,55 @@ note: required by a bound in `check`
4545
LL | const fn check<T: ~const Destruct>(_: T) {}
4646
| ^^^^^^^^^^^^^^^ required by this bound in `check`
4747

48-
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
48+
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
49+
--> $DIR/const-drop-fail.rs:48:47
50+
|
51+
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
52+
| ----------------------------------------- ^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
53+
| |
54+
| required by a bound introduced by this call
55+
|
56+
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
57+
--> $DIR/const-drop-fail.rs:48:47
58+
|
59+
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
60+
| ^^^^^^^^^^^
61+
note: required by a bound in `ConstDropImplWithBounds`
62+
--> $DIR/const-drop-fail.rs:27:35
63+
|
64+
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
65+
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
66+
67+
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
68+
--> $DIR/const-drop-fail.rs:48:5
69+
|
70+
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
71+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
72+
|
73+
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
4974
--> $DIR/const-drop-fail.rs:48:5
5075
|
51-
LL | const _: () = check($exp);
52-
| ----- required by a bound introduced by this call
53-
...
5476
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
78+
note: required by a bound in `ConstDropImplWithBounds`
79+
--> $DIR/const-drop-fail.rs:27:35
5680
|
57-
note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
58-
--> $DIR/const-drop-fail.rs:29:25
81+
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
82+
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
83+
84+
error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
85+
--> $DIR/const-drop-fail.rs:55:9
5986
|
60-
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
61-
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
62-
= note: 1 redundant requirement hidden
63-
= note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
64-
note: required by a bound in `check`
65-
--> $DIR/const-drop-fail.rs:35:19
87+
LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
88+
| ^^^^^^^^
6689
|
67-
LL | const fn check<T: ~const Destruct>(_: T) {}
68-
| ^^^^^^^^^^^^^^^ required by this bound in `check`
69-
help: consider borrowing here
90+
note: the implementor must specify the same requirement
91+
--> $DIR/const-drop-fail.rs:53:1
7092
|
71-
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
72-
| +
73-
LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
74-
| ++++
93+
LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
94+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7595

76-
error: aborting due to 3 previous errors
96+
error: aborting due to 5 previous errors
7797

78-
For more information about this error, try `rustc --explain E0277`.
98+
Some errors have detailed explanations: E0277, E0367.
99+
For more information about an error, try `rustc --explain E0277`.

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

+11-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ trait A { fn a() { } }
2424

2525
impl A for NonTrivialDrop {}
2626

27-
struct ConstDropImplWithBounds<T: A>(PhantomData<T>);
27+
struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
2828

2929
impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
3030
fn drop(&mut self) {
@@ -47,6 +47,16 @@ check_all! {
4747
//~^ ERROR can't drop
4848
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
4949
//~^ ERROR the trait bound
50+
//~| ERROR the trait bound
51+
}
52+
53+
struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
54+
55+
impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
56+
//~^ ERROR `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
57+
fn drop(&mut self) {
58+
T::a();
59+
}
5060
}
5161

5262
fn main() {}

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

+43-22
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,55 @@ note: required by a bound in `check`
4545
LL | const fn check<T: ~const Destruct>(_: T) {}
4646
| ^^^^^^^^^^^^^^^ required by this bound in `check`
4747

48-
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
48+
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
49+
--> $DIR/const-drop-fail.rs:48:47
50+
|
51+
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
52+
| ----------------------------------------- ^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
53+
| |
54+
| required by a bound introduced by this call
55+
|
56+
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
57+
--> $DIR/const-drop-fail.rs:48:47
58+
|
59+
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
60+
| ^^^^^^^^^^^
61+
note: required by a bound in `ConstDropImplWithBounds`
62+
--> $DIR/const-drop-fail.rs:27:35
63+
|
64+
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
65+
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
66+
67+
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
68+
--> $DIR/const-drop-fail.rs:48:5
69+
|
70+
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
71+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
72+
|
73+
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
4974
--> $DIR/const-drop-fail.rs:48:5
5075
|
51-
LL | const _: () = check($exp);
52-
| ----- required by a bound introduced by this call
53-
...
5476
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
78+
note: required by a bound in `ConstDropImplWithBounds`
79+
--> $DIR/const-drop-fail.rs:27:35
5680
|
57-
note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
58-
--> $DIR/const-drop-fail.rs:29:25
81+
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
82+
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
83+
84+
error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
85+
--> $DIR/const-drop-fail.rs:55:9
5986
|
60-
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
61-
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
62-
= note: 1 redundant requirement hidden
63-
= note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
64-
note: required by a bound in `check`
65-
--> $DIR/const-drop-fail.rs:35:19
87+
LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
88+
| ^^^^^^^^
6689
|
67-
LL | const fn check<T: ~const Destruct>(_: T) {}
68-
| ^^^^^^^^^^^^^^^ required by this bound in `check`
69-
help: consider borrowing here
90+
note: the implementor must specify the same requirement
91+
--> $DIR/const-drop-fail.rs:53:1
7092
|
71-
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
72-
| +
73-
LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
74-
| ++++
93+
LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
94+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7595

76-
error: aborting due to 3 previous errors
96+
error: aborting due to 5 previous errors
7797

78-
For more information about this error, try `rustc --explain E0277`.
98+
Some errors have detailed explanations: E0277, E0367.
99+
For more information about an error, try `rustc --explain E0277`.

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ mod t {
6060
fn foo() {}
6161
}
6262

63-
pub struct ConstDropWithBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
63+
pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
6464

6565
impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
6666
fn drop(&mut self) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
#![feature(const_trait_impl)]
3+
4+
#[const_trait]
5+
trait Foo {
6+
fn foo(&self) {}
7+
}
8+
9+
struct Bar<T>(T);
10+
11+
impl<T: ~const Foo> Bar<T> {
12+
const fn foo(&self) {
13+
self.0.foo()
14+
}
15+
}
16+
17+
fn main() {}

0 commit comments

Comments
 (0)