From bbfe1c1ec3bcaaa51446f89e66641561751f38f8 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Sat, 17 Feb 2024 21:40:23 +0100 Subject: [PATCH] lint implied bounds in APIT --- clippy_lints/src/implied_bounds_in_impls.rs | 18 +++++++++++++++++- tests/ui/implied_bounds_in_impls.fixed | 2 +- tests/ui/implied_bounds_in_impls.stderr | 14 +++++++++++++- 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::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 {} } -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 @@ -228,6 +228,18 @@ LL - fn f5() -> impl X + Y {} LL + fn f5() -> impl Y {} | +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 | @@ -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