diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-10-21 13:49:11 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-10-21 14:22:13 +0000 |
| commit | d6cf8934db2af8b56f37b235c5aa66593d1eb22c (patch) | |
| tree | 866302db5b1ad7e66dfb50369bc5f5d37435bf5d | |
| parent | 349ba6bb51f53d93286600a0a078fefafff9e0d3 (diff) | |
| download | rust-d6cf8934db2af8b56f37b235c5aa66593d1eb22c.tar.gz rust-d6cf8934db2af8b56f37b235c5aa66593d1eb22c.zip | |
Require Drop impls to have the same constness on its bounds as the bounds on the struct have
6 files changed, 116 insertions, 53 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index e5b212eb757..3d55ffc595f 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -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() diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index ddf0e2d91c0..796c0d388ea 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -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 | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` --> $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>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail.rs:27:35 | -note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct` - --> $DIR/const-drop-fail.rs:29:25 +LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +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 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 | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { + | ^^^^^^^^ | -LL | const fn check<T: ~const Destruct>(_: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `check` -help: consider borrowing here +note: the implementor must specify the same requirement + --> $DIR/const-drop-fail.rs:53:1 | -LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), - | + -LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), - | ++++ +LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0367. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs index 565e2c77ac5..d36c7f81ced 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs @@ -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() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index ddf0e2d91c0..796c0d388ea 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -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 | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` --> $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>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail.rs:27:35 | -note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct` - --> $DIR/const-drop-fail.rs:29:25 +LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +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 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 | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { + | ^^^^^^^^ | -LL | const fn check<T: ~const Destruct>(_: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `check` -help: consider borrowing here +note: the implementor must specify the same requirement + --> $DIR/const-drop-fail.rs:53:1 | -LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), - | + -LL | &mut ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), - | ++++ +LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0367. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs index 8b4c4065815..b0fc3adf984 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs @@ -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) { diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs new file mode 100644 index 00000000000..285cef571f3 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs @@ -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() {} |
