Require Drop impls to have the same constness on its bounds as the bounds on the struct have

This commit is contained in:
Oli Scherer 2022-10-21 13:49:11 +00:00
parent 349ba6bb51
commit d6cf8934db
6 changed files with 118 additions and 55 deletions

View File

@ -184,13 +184,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
let p = p.kind();
match (predicate.skip_binder(), p.skip_binder()) {
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => {
// Since struct predicates cannot have ~const, project the impl predicate
// onto one that ignores the constness. This is equivalent to saying that
// we match a `Trait` bound on the struct with a `Trait` or `~const Trait`
// in the impl.
let non_const_a =
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..a };
relator.relate(predicate.rebind(non_const_a), p.rebind(b)).is_ok()
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
}
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()

View File

@ -45,34 +45,55 @@ note: required by a bound in `check`
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
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
--> $DIR/const-drop-fail.rs:48:47
|
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ----------------------------------------- ^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
| |
| required by a bound introduced by this call
|
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:48:47
|
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^
note: required by a bound in `ConstDropImplWithBounds`
--> $DIR/const-drop-fail.rs:27:35
|
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
--> $DIR/const-drop-fail.rs:48:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
...
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
|
note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
--> $DIR/const-drop-fail.rs:29:25
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:48:5
|
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:35:19
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `ConstDropImplWithBounds`
--> $DIR/const-drop-fail.rs:27:35
|
LL | const fn check<T: ~const Destruct>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `check`
help: consider borrowing here
|
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| +
LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ++++
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
error: aborting due to 3 previous errors
error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
--> $DIR/const-drop-fail.rs:55:9
|
LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
| ^^^^^^^^
|
note: the implementor must specify the same requirement
--> $DIR/const-drop-fail.rs:53:1
|
LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0277`.
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0367.
For more information about an error, try `rustc --explain E0277`.

View File

@ -24,7 +24,7 @@ trait A { fn a() { } }
impl A for NonTrivialDrop {}
struct ConstDropImplWithBounds<T: A>(PhantomData<T>);
struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
fn drop(&mut self) {
@ -47,6 +47,16 @@ check_all! {
//~^ ERROR can't drop
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
//~^ ERROR the trait bound
//~| ERROR the trait bound
}
struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
//~^ ERROR `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
fn drop(&mut self) {
T::a();
}
}
fn main() {}

View File

@ -45,34 +45,55 @@ note: required by a bound in `check`
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
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
--> $DIR/const-drop-fail.rs:48:47
|
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ----------------------------------------- ^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
| |
| required by a bound introduced by this call
|
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:48:47
|
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^
note: required by a bound in `ConstDropImplWithBounds`
--> $DIR/const-drop-fail.rs:27:35
|
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
--> $DIR/const-drop-fail.rs:48:5
|
LL | const _: () = check($exp);
| ----- required by a bound introduced by this call
...
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
|
note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
--> $DIR/const-drop-fail.rs:29:25
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:48:5
|
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:35:19
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `ConstDropImplWithBounds`
--> $DIR/const-drop-fail.rs:27:35
|
LL | const fn check<T: ~const Destruct>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `check`
help: consider borrowing here
|
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| +
LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
| ++++
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
error: aborting due to 3 previous errors
error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
--> $DIR/const-drop-fail.rs:55:9
|
LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
| ^^^^^^^^
|
note: the implementor must specify the same requirement
--> $DIR/const-drop-fail.rs:53:1
|
LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0277`.
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0367.
For more information about an error, try `rustc --explain E0277`.

View File

@ -60,7 +60,7 @@ mod t {
fn foo() {}
}
pub struct ConstDropWithBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
fn drop(&mut self) {

View File

@ -0,0 +1,17 @@
// check-pass
#![feature(const_trait_impl)]
#[const_trait]
trait Foo {
fn foo(&self) {}
}
struct Bar<T>(T);
impl<T: ~const Foo> Bar<T> {
const fn foo(&self) {
self.0.foo()
}
}
fn main() {}