about summary refs log tree commit diff
diff options
context:
space:
mode:
authory21 <30553356+y21@users.noreply.github.com>2024-02-17 21:40:23 +0100
committery21 <30553356+y21@users.noreply.github.com>2024-02-25 23:12:28 +0100
commitbbfe1c1ec3bcaaa51446f89e66641561751f38f8 (patch)
tree5d1a499c2e003fc17ba5540a3750ae8dfb0231d4
parentec29b0d6b819bc88c4a411a8104e684032324b9e (diff)
downloadrust-bbfe1c1ec3bcaaa51446f89e66641561751f38f8.tar.gz
rust-bbfe1c1ec3bcaaa51446f89e66641561751f38f8.zip
lint implied bounds in APIT
-rw-r--r--clippy_lints/src/implied_bounds_in_impls.rs18
-rw-r--r--tests/ui/implied_bounds_in_impls.fixed2
-rw-r--r--tests/ui/implied_bounds_in_impls.stderr14
3 files changed, 31 insertions, 3 deletions
diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs
index 9efe3993ca5..74582f7f1de 100644
--- a/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/clippy_lints/src/implied_bounds_in_impls.rs
@@ -2,7 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::def_id::DefId;
-use rustc_hir::{GenericArg, GenericBound, GenericBounds, ItemKind, TraitBoundModifier, TyKind, TypeBinding};
+use rustc_hir::{
+    GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
+    WherePredicate,
+};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
@@ -326,6 +329,19 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
 }
 
 impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
+    fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &rustc_hir::Generics<'tcx>) {
+        for predicate in generics.predicates {
+            if let WherePredicate::BoundPredicate(predicate) = predicate
+                // In theory, the origin doesn't really matter,
+                // we *could* also lint on explicit where clauses written out by the user,
+                // not just impl trait desugared ones, but that contradicts with the lint name...
+                && let PredicateOrigin::ImplTrait = predicate.origin
+            {
+                check(cx, predicate.bounds);
+            }
+        }
+    }
+
     fn check_ty(&mut self, cx: &LateContext<'_>, ty: &rustc_hir::Ty<'_>) {
         if let TyKind::OpaqueDef(item_id, ..) = ty.kind
             && let item = cx.tcx.hir().item(item_id)
diff --git a/tests/ui/implied_bounds_in_impls.fixed b/tests/ui/implied_bounds_in_impls.fixed
index d65fc97ebbf..6fd4cbd80fe 100644
--- a/tests/ui/implied_bounds_in_impls.fixed
+++ b/tests/ui/implied_bounds_in_impls.fixed
@@ -151,7 +151,7 @@ fn issue11880() {
     fn f5() -> impl Y<T = u32, U = String> {}
 }
 
-fn apit(_: impl Deref + DerefMut) {}
+fn apit(_: impl DerefMut) {}
 
 trait Rpitit {
     fn f() -> impl DerefMut;
diff --git a/tests/ui/implied_bounds_in_impls.stderr b/tests/ui/implied_bounds_in_impls.stderr
index 9505deee351..805532a5680 100644
--- a/tests/ui/implied_bounds_in_impls.stderr
+++ b/tests/ui/implied_bounds_in_impls.stderr
@@ -229,6 +229,18 @@ LL +     fn f5() -> impl Y<T = u32, U = String> {}
    |
 
 error: this bound is already specified as the supertrait of `DerefMut`
+  --> tests/ui/implied_bounds_in_impls.rs:154:17
+   |
+LL | fn apit(_: impl Deref + DerefMut) {}
+   |                 ^^^^^
+   |
+help: try removing this bound
+   |
+LL - fn apit(_: impl Deref + DerefMut) {}
+LL + fn apit(_: impl DerefMut) {}
+   |
+
+error: this bound is already specified as the supertrait of `DerefMut`
   --> tests/ui/implied_bounds_in_impls.rs:157:20
    |
 LL |     fn f() -> impl Deref + DerefMut;
@@ -264,5 +276,5 @@ LL - type Tait = impl Deref + DerefMut;
 LL + type Tait = impl DerefMut;
    |
 
-error: aborting due to 22 previous errors
+error: aborting due to 23 previous errors