lint implied bounds in APIT

This commit is contained in:
y21 2024-02-17 21:40:23 +01:00
parent ec29b0d6b8
commit bbfe1c1ec3
3 changed files with 31 additions and 3 deletions

View File

@ -2,7 +2,10 @@
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::{Applicability, SuggestionStyle};
use rustc_hir::def_id::DefId; 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_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt}; 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 { 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<'_>) { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &rustc_hir::Ty<'_>) {
if let TyKind::OpaqueDef(item_id, ..) = ty.kind if let TyKind::OpaqueDef(item_id, ..) = ty.kind
&& let item = cx.tcx.hir().item(item_id) && let item = cx.tcx.hir().item(item_id)

View File

@ -151,7 +151,7 @@ fn issue11880() {
fn f5() -> impl Y<T = u32, U = String> {} fn f5() -> impl Y<T = u32, U = String> {}
} }
fn apit(_: impl Deref + DerefMut) {} fn apit(_: impl DerefMut) {}
trait Rpitit { trait Rpitit {
fn f() -> impl DerefMut; fn f() -> impl DerefMut;

View File

@ -228,6 +228,18 @@ LL - fn f5() -> impl X<U = String> + Y<T = u32> {}
LL + fn f5() -> impl Y<T = u32, U = String> {} 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` error: this bound is already specified as the supertrait of `DerefMut`
--> tests/ui/implied_bounds_in_impls.rs:157:20 --> tests/ui/implied_bounds_in_impls.rs:157:20
| |
@ -264,5 +276,5 @@ LL - type Tait = impl Deref + DerefMut;
LL + type Tait = impl DerefMut; LL + type Tait = impl DerefMut;
| |
error: aborting due to 22 previous errors error: aborting due to 23 previous errors