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
6 changed files with 118 additions and 55 deletions
|
@ -184,13 +184,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||||
let p = p.kind();
|
let p = p.kind();
|
||||||
match (predicate.skip_binder(), p.skip_binder()) {
|
match (predicate.skip_binder(), p.skip_binder()) {
|
||||||
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => {
|
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => {
|
||||||
// Since struct predicates cannot have ~const, project the impl predicate
|
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
|
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
|
||||||
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
|
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) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ 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
|
--> $DIR/const-drop-fail.rs:48:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ----- required by a bound introduced by this call
|
|
||||||
...
|
|
||||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
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`
|
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||||
--> $DIR/const-drop-fail.rs:29:25
|
--> $DIR/const-drop-fail.rs:48:5
|
||||||
|
|
|
|
||||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: 1 redundant requirement hidden
|
note: required by a bound in `ConstDropImplWithBounds`
|
||||||
= note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
|
--> $DIR/const-drop-fail.rs:27:35
|
||||||
note: required by a bound in `check`
|
|
||||||
--> $DIR/const-drop-fail.rs:35:19
|
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
|
||||||
help: consider borrowing here
|
|
||||||
|
|
|
||||||
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
|
||||||
| +
|
|
||||||
LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
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 {}
|
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> {
|
impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -47,6 +47,16 @@ check_all! {
|
||||||
//~^ ERROR can't drop
|
//~^ ERROR can't drop
|
||||||
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||||
//~^ ERROR the trait bound
|
//~^ 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() {}
|
fn main() {}
|
||||||
|
|
|
@ -45,34 +45,55 @@ note: required by a bound in `check`
|
||||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ 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
|
--> $DIR/const-drop-fail.rs:48:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ----- required by a bound introduced by this call
|
|
||||||
...
|
|
||||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
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`
|
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||||
--> $DIR/const-drop-fail.rs:29:25
|
--> $DIR/const-drop-fail.rs:48:5
|
||||||
|
|
|
|
||||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: 1 redundant requirement hidden
|
note: required by a bound in `ConstDropImplWithBounds`
|
||||||
= note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
|
--> $DIR/const-drop-fail.rs:27:35
|
||||||
note: required by a bound in `check`
|
|
||||||
--> $DIR/const-drop-fail.rs:35:19
|
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
|
||||||
help: consider borrowing here
|
|
||||||
|
|
|
||||||
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
|
||||||
| +
|
|
||||||
LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
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() {}
|
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> {
|
impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
|
||||||
fn drop(&mut self) {
|
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…
Add table
Add a link
Reference in a new issue