Require Drop impls to have the same constness on its bounds as the bounds on the struct have
This commit is contained in:
parent
349ba6bb51
commit
d6cf8934db
@ -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()
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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`.
|
||||
|
@ -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) {
|
||||
|
@ -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() {}
|
Loading…
x
Reference in New Issue
Block a user