about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/implied_bounds_in_impls.fixed68
-rw-r--r--tests/ui/implied_bounds_in_impls.rs68
-rw-r--r--tests/ui/implied_bounds_in_impls.stderr123
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
+