diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/implied_bounds_in_impls.fixed | 68 | ||||
| -rw-r--r-- | tests/ui/implied_bounds_in_impls.rs | 68 | ||||
| -rw-r--r-- | tests/ui/implied_bounds_in_impls.stderr | 123 |
3 files changed, 259 insertions, 0 deletions
diff --git a/tests/ui/implied_bounds_in_impls.fixed b/tests/ui/implied_bounds_in_impls.fixed new file mode 100644 index 00000000000..952c2b70619 --- /dev/null +++ b/tests/ui/implied_bounds_in_impls.fixed @@ -0,0 +1,68 @@ +#![warn(clippy::implied_bounds_in_impls)] +#![allow(dead_code)] +#![feature(return_position_impl_trait_in_trait)] + +use std::ops::{Deref, DerefMut}; + +// Only one bound, nothing to lint. +fn normal_deref<T>(x: T) -> impl Deref<Target = T> { + Box::new(x) +} + +// Deref implied by DerefMut +fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> { + Box::new(x) +} + +trait GenericTrait<T> {} +trait GenericTrait2<V> {} +// U is intentionally at a different "index" in GenericSubtrait than `T` is in GenericTrait, +// so this can be a good test to make sure that the calculations are right (no off-by-one errors, +// ...) +trait GenericSubtrait<T, U, V>: GenericTrait<U> + GenericTrait2<V> {} + +impl GenericTrait<i32> for () {} +impl GenericTrait<i64> for () {} +impl<V> GenericTrait2<V> for () {} +impl<V> GenericSubtrait<(), i32, V> for () {} +impl<V> GenericSubtrait<(), i64, V> for () {} + +fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U> +where + (): GenericSubtrait<U, W, U>, +{ +} + +fn generics_implied_multi<V>() -> impl GenericSubtrait<(), i32, V> {} + +fn generics_implied_multi2<T, V>() -> impl GenericSubtrait<(), T, V> +where + (): GenericSubtrait<(), T, V> + GenericTrait<T>, +{ +} + +// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint +fn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {} + +// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint +fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} + +trait SomeTrait { + // Check that it works in trait declarations. + fn f() -> impl DerefMut<Target = u8>; +} +struct SomeStruct; +impl SomeStruct { + // Check that it works in inherent impl blocks. + fn f() -> impl DerefMut<Target = u8> { + Box::new(123) + } +} +impl SomeTrait for SomeStruct { + // Check that it works in trait impls. + fn f() -> impl DerefMut<Target = u8> { + Box::new(42) + } +} + +fn main() {} diff --git a/tests/ui/implied_bounds_in_impls.rs b/tests/ui/implied_bounds_in_impls.rs new file mode 100644 index 00000000000..475f2621bbf --- /dev/null +++ b/tests/ui/implied_bounds_in_impls.rs @@ -0,0 +1,68 @@ +#![warn(clippy::implied_bounds_in_impls)] +#![allow(dead_code)] +#![feature(return_position_impl_trait_in_trait)] + +use std::ops::{Deref, DerefMut}; + +// Only one bound, nothing to lint. +fn normal_deref<T>(x: T) -> impl Deref<Target = T> { + Box::new(x) +} + +// Deref implied by DerefMut +fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> { + Box::new(x) +} + +trait GenericTrait<T> {} +trait GenericTrait2<V> {} +// U is intentionally at a different "index" in GenericSubtrait than `T` is in GenericTrait, +// so this can be a good test to make sure that the calculations are right (no off-by-one errors, +// ...) +trait GenericSubtrait<T, U, V>: GenericTrait<U> + GenericTrait2<V> {} + +impl GenericTrait<i32> for () {} +impl GenericTrait<i64> for () {} +impl<V> GenericTrait2<V> for () {} +impl<V> GenericSubtrait<(), i32, V> for () {} +impl<V> GenericSubtrait<(), i64, V> for () {} + +fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U> +where + (): GenericSubtrait<U, W, U>, +{ +} + +fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} + +fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> +where + (): GenericSubtrait<(), T, V> + GenericTrait<T>, +{ +} + +// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint +fn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {} + +// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint +fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {} + +trait SomeTrait { + // Check that it works in trait declarations. + fn f() -> impl Deref + DerefMut<Target = u8>; +} +struct SomeStruct; +impl SomeStruct { + // Check that it works in inherent impl blocks. + fn f() -> impl Deref + DerefMut<Target = u8> { + Box::new(123) + } +} +impl SomeTrait for SomeStruct { + // Check that it works in trait impls. + fn f() -> impl Deref + DerefMut<Target = u8> { + Box::new(42) + } +} + +fn main() {} diff --git a/tests/ui/implied_bounds_in_impls.stderr b/tests/ui/implied_bounds_in_impls.stderr new file mode 100644 index 00000000000..8dffc674444 --- /dev/null +++ b/tests/ui/implied_bounds_in_impls.stderr @@ -0,0 +1,123 @@ +error: this bound is already specified as the supertrait of `DerefMut<Target = T>` + --> $DIR/implied_bounds_in_impls.rs:13:36 + | +LL | fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> { + | ^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::implied-bounds-in-impls` implied by `-D warnings` +help: try removing this bound + | +LL - fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> { +LL + fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> { + | + +error: this bound is already specified as the supertrait of `GenericSubtrait<U, W, U>` + --> $DIR/implied_bounds_in_impls.rs:30:37 + | +LL | fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U> + | ^^^^^^^^^^^^^^^ + | +help: try removing this bound + | +LL - fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U> +LL + fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U> + | + +error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` + --> $DIR/implied_bounds_in_impls.rs:36:40 + | +LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} + | ^^^^^^^^^^^^^^^^^ + | +help: try removing this bound + | +LL - fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} +LL + fn generics_implied_multi<V>() -> impl GenericTrait2<V> + GenericSubtrait<(), i32, V> {} + | + +error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` + --> $DIR/implied_bounds_in_impls.rs:36:60 + | +LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} + | ^^^^^^^^^^^^^^^^ + | +help: try removing this bound + | +LL - fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} +LL + fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, V> {} + | + +error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` + --> $DIR/implied_bounds_in_impls.rs:38:44 + | +LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> + | ^^^^^^^^^^^^^^^ + | +help: try removing this bound + | +LL - fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> +LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait2<V> + GenericSubtrait<(), T, V> + | + +error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` + --> $DIR/implied_bounds_in_impls.rs:38:62 + | +LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> + | ^^^^^^^^^^^^^^^^ + | +help: try removing this bound + | +LL - fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> +LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericSubtrait<(), T, V> + | + +error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>` + --> $DIR/implied_bounds_in_impls.rs:48:28 + | +LL | fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {} + | ^^^^^^^^^^^^^^^^^ + | +help: try removing this bound + | +LL - fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {} +LL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} + | + +error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` + --> $DIR/implied_bounds_in_impls.rs:52:20 + | +LL | fn f() -> impl Deref + DerefMut<Target = u8>; + | ^^^^^ + | +help: try removing this bound + | +LL - fn f() -> impl Deref + DerefMut<Target = u8>; +LL + fn f() -> impl DerefMut<Target = u8>; + | + +error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` + --> $DIR/implied_bounds_in_impls.rs:57:20 + | +LL | fn f() -> impl Deref + DerefMut<Target = u8> { + | ^^^^^ + | +help: try removing this bound + | +LL - fn f() -> impl Deref + DerefMut<Target = u8> { +LL + fn f() -> impl DerefMut<Target = u8> { + | + +error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` + --> $DIR/implied_bounds_in_impls.rs:63:20 + | +LL | fn f() -> impl Deref + DerefMut<Target = u8> { + | ^^^^^ + | +help: try removing this bound + | +LL - fn f() -> impl Deref + DerefMut<Target = u8> { +LL + fn f() -> impl DerefMut<Target = u8> { + | + +error: aborting due to 10 previous errors + |
