diff --git a/tests/ui/dropck/explicit-drop-bounds.bad1.stderr b/tests/ui/dropck/explicit-drop-bounds.bad1.stderr new file mode 100644 index 0000000000000..3b506c7e7ec13 --- /dev/null +++ b/tests/ui/dropck/explicit-drop-bounds.bad1.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:27:18 + | +LL | impl Drop for DropMe + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe(T); + | ^^^^ required by this bound in `DropMe` +help: consider further restricting type parameter `T` + | +LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy` + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:32:13 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe(T); + | ^^^^ required by this bound in `DropMe` +help: consider further restricting type parameter `T` + | +LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy` + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dropck/explicit-drop-bounds.bad2.stderr b/tests/ui/dropck/explicit-drop-bounds.bad2.stderr new file mode 100644 index 0000000000000..832af3e521a9d --- /dev/null +++ b/tests/ui/dropck/explicit-drop-bounds.bad2.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:37:18 + | +LL | impl Drop for DropMe + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe(T); + | ^^^^ required by this bound in `DropMe` +help: consider restricting type parameter `T` + | +LL | impl Drop for DropMe + | +++++++++++++++++++ + +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/explicit-drop-bounds.rs:40:13 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `DropMe` + --> $DIR/explicit-drop-bounds.rs:7:18 + | +LL | struct DropMe(T); + | ^^^^ required by this bound in `DropMe` +help: consider restricting type parameter `T` + | +LL | impl Drop for DropMe + | +++++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dropck/explicit-drop-bounds.rs b/tests/ui/dropck/explicit-drop-bounds.rs new file mode 100644 index 0000000000000..ab6f33c09994e --- /dev/null +++ b/tests/ui/dropck/explicit-drop-bounds.rs @@ -0,0 +1,44 @@ +// revisions: good1 good2 bad1 bad2 +//[good1] check-pass +//[good2] check-pass + +use std::ops::Drop; + +struct DropMe(T); + +#[cfg(good1)] +impl Drop for DropMe +where + T: Copy + Clone, +{ + fn drop(&mut self) {} +} + +#[cfg(good2)] +impl Drop for DropMe +where + T: Copy, + [T; 1]: Copy, // Trivial bound implied by `T: Copy` +{ + fn drop(&mut self) {} +} + +#[cfg(bad1)] +impl Drop for DropMe +//[bad1]~^ ERROR the trait bound `T: Copy` is not satisfied +where + [T; 1]: Copy, // But `[T; 1]: Copy` does not imply `T: Copy` +{ + fn drop(&mut self) {} + //[bad1]~^ ERROR the trait bound `T: Copy` is not satisfied +} + +#[cfg(bad2)] +impl Drop for DropMe +//[bad2]~^ ERROR the trait bound `T: Copy` is not satisfied +{ + fn drop(&mut self) {} + //[bad2]~^ ERROR the trait bound `T: Copy` is not satisfied +} + +fn main() {} diff --git a/tests/ui/dropck/explicit-implied-outlives.bad1.stderr b/tests/ui/dropck/explicit-implied-outlives.bad1.stderr new file mode 100644 index 0000000000000..bf6d70e7d3758 --- /dev/null +++ b/tests/ui/dropck/explicit-implied-outlives.bad1.stderr @@ -0,0 +1,15 @@ +error[E0367]: `Drop` impl requires `T: 'static` but the struct it is implemented for does not + --> $DIR/explicit-implied-outlives.rs:28:8 + | +LL | T: 'static, + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/explicit-implied-outlives.rs:7:1 + | +LL | struct DropMe<'a, T>(&'a T); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/dropck/explicit-implied-outlives.bad2.stderr b/tests/ui/dropck/explicit-implied-outlives.bad2.stderr new file mode 100644 index 0000000000000..27a15170bddb5 --- /dev/null +++ b/tests/ui/dropck/explicit-implied-outlives.bad2.stderr @@ -0,0 +1,15 @@ +error[E0367]: `Drop` impl requires `'a: 'static` but the struct it is implemented for does not + --> $DIR/explicit-implied-outlives.rs:37:9 + | +LL | 'a: 'static, + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/explicit-implied-outlives.rs:7:1 + | +LL | struct DropMe<'a, T>(&'a T); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/dropck/explicit-implied-outlives.rs b/tests/ui/dropck/explicit-implied-outlives.rs new file mode 100644 index 0000000000000..fa446591f3dc4 --- /dev/null +++ b/tests/ui/dropck/explicit-implied-outlives.rs @@ -0,0 +1,43 @@ +// revisions: good1 good2 bad1 bad2 +//[good1] check-pass +//[good2] check-pass + +use std::ops::Drop; + +struct DropMe<'a, T>(&'a T); + +#[cfg(good1)] +impl<'a, T> Drop for DropMe<'a, T> +where + T: 'a, // Implied by struct, explicit on impl +{ + fn drop(&mut self) {} +} + +#[cfg(good2)] +impl<'a, T> Drop for DropMe<'a, T> +where + 'static: 'a, // Trivial bound +{ + fn drop(&mut self) {} +} + +#[cfg(bad1)] +impl<'a, T> Drop for DropMe<'a, T> +where + T: 'static, + //[bad1]~^ ERROR `Drop` impl requires `T: 'static` +{ + fn drop(&mut self) {} +} + +#[cfg(bad2)] +impl<'a, T> Drop for DropMe<'a, T> +where + 'a: 'static, + //[bad2]~^ ERROR `Drop` impl requires `'a: 'static` +{ + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/transitive-outlives-2.rs b/tests/ui/dropck/transitive-outlives-2.rs new file mode 100644 index 0000000000000..87154e25d4091 --- /dev/null +++ b/tests/ui/dropck/transitive-outlives-2.rs @@ -0,0 +1,18 @@ +// check-pass + +use std::marker::PhantomData; +use std::ops::Drop; + +// a >= b >= c >= a implies a = b = c +struct DropMe<'a: 'b, 'b: 'c, 'c: 'a>( + PhantomData<&'a ()>, + PhantomData<&'b ()>, + PhantomData<&'c ()>, +); + +// a >= b, a >= c, b >= a, c >= a implies a = b = c +impl<'a: 'b + 'c, 'b: 'a, 'c: 'a> Drop for DropMe<'a, 'b, 'c> { + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/transitive-outlives.bad.stderr b/tests/ui/dropck/transitive-outlives.bad.stderr new file mode 100644 index 0000000000000..da5088b27b414 --- /dev/null +++ b/tests/ui/dropck/transitive-outlives.bad.stderr @@ -0,0 +1,15 @@ +error[E0367]: `Drop` impl requires `'a: 'c` but the struct it is implemented for does not + --> $DIR/transitive-outlives.rs:20:9 + | +LL | 'a: 'c, + | ^^ + | +note: the implementor must specify the same requirement + --> $DIR/transitive-outlives.rs:7:1 + | +LL | struct DropMe<'a, 'b: 'a, 'c: 'b>(PhantomData<&'a ()>, PhantomData<&'b ()>, PhantomData<&'c ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0367`. diff --git a/tests/ui/dropck/transitive-outlives.rs b/tests/ui/dropck/transitive-outlives.rs new file mode 100644 index 0000000000000..d071664abdeb6 --- /dev/null +++ b/tests/ui/dropck/transitive-outlives.rs @@ -0,0 +1,26 @@ +// revisions: good bad +//[good] check-pass + +use std::marker::PhantomData; +use std::ops::Drop; + +struct DropMe<'a, 'b: 'a, 'c: 'b>(PhantomData<&'a ()>, PhantomData<&'b ()>, PhantomData<&'c ()>); + +#[cfg(good)] +impl<'a, 'b, 'c> Drop for DropMe<'a, 'b, 'c> +where + 'c: 'a, +{ + fn drop(&mut self) {} +} + +#[cfg(bad)] +impl<'a, 'b, 'c> Drop for DropMe<'a, 'b, 'c> +where + 'a: 'c, + //[bad]~^ ERROR `Drop` impl requires `'a: 'c` +{ + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/dropck/trivial-impl-bounds.rs b/tests/ui/dropck/trivial-impl-bounds.rs new file mode 100644 index 0000000000000..a8f5d2c354bc9 --- /dev/null +++ b/tests/ui/dropck/trivial-impl-bounds.rs @@ -0,0 +1,34 @@ +// revisions: good1 good2 good3 +// check-pass + +use std::ops::Drop; + +struct Foo; + +const X: usize = 1; + +#[cfg(good1)] +impl Drop for Foo +where + [(); X]:, // Trivial WF bound +{ + fn drop(&mut self) {} +} + +#[cfg(good2)] +impl Drop for Foo +where + for<'a> &'a (): Copy, // Trivial trait bound +{ + fn drop(&mut self) {} +} + +#[cfg(good3)] +impl Drop for Foo +where + for<'a> &'a (): 'a, // Trivial outlives bound +{ + fn drop(&mut self) {} +} + +fn main() {}