support inherent impls and trait impls

This commit is contained in:
y21 2023-08-23 16:48:12 +02:00
parent 09506f49c1
commit 12275713d5
4 changed files with 124 additions and 87 deletions

View File

@ -1,11 +1,14 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, FnRetTy, GenericArg, GenericBound, ItemKind, TraitBoundModifier, TyKind};
use rustc_hir::{
Body, FnDecl, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, ItemKind, TraitBoundModifier, TraitItem,
TraitItemKind, TyKind,
};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_middle::ty::{self, ClauseKind, TyCtxt};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span;
@ -94,16 +97,7 @@ fn is_same_generics(
})
}
impl LateLintPass<'_> for ImpliedBoundsInImpls {
fn check_fn(
&mut self,
cx: &LateContext<'_>,
_: FnKind<'_>,
decl: &FnDecl<'_>,
_: &Body<'_>,
_: Span,
_: LocalDefId,
) {
fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
if let FnRetTy::Return(ty) = decl.output
&&let TyKind::OpaqueDef(item_id, ..) = ty.kind
&& let item = cx.tcx.hir().item(item_id)
@ -158,7 +152,7 @@ fn check_fn(
span_lint_and_then(
cx, IMPLIED_BOUNDS_IN_IMPLS,
poly_trait.span,
&format!("this bound is already specified as the supertrait of `{}`", implied_by),
&format!("this bound is already specified as the supertrait of `{implied_by}`"),
|diag| {
// If we suggest removing a bound, we may also need extend the span
// to include the `+` token, so we don't end up with something like `impl + B`
@ -181,5 +175,28 @@ fn check_fn(
}
}
}
}
impl LateLintPass<'_> for ImpliedBoundsInImpls {
fn check_fn(
&mut self,
cx: &LateContext<'_>,
_: FnKind<'_>,
decl: &FnDecl<'_>,
_: &Body<'_>,
_: Span,
_: LocalDefId,
) {
check(cx, decl);
}
fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
if let TraitItemKind::Fn(sig, ..) = &item.kind {
check(cx, sig.decl);
}
}
fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &ImplItem<'_>) {
if let ImplItemKind::Fn(sig, ..) = &item.kind {
check(cx, sig.decl);
}
}
}

View File

@ -49,9 +49,7 @@ fn generics_same() -> impl GenericSubtrait<(), i32, ()> {}
trait SomeTrait {
// Check that it works in trait declarations.
fn f() -> impl DerefMut<Target = u8> {
Box::new(0)
}
fn f() -> impl DerefMut<Target = u8>;
}
struct SomeStruct;
impl SomeStruct {

View File

@ -49,20 +49,18 @@ fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}
trait SomeTrait {
// Check that it works in trait declarations.
fn f() -> impl Deref + DerefMut<Target = u8> {
Box::new(0)
}
fn f() -> impl Deref + DerefMut<Target = u8>;
}
struct SomeStruct;
impl SomeStruct {
// Check that it works in inherent impl blocks.
fn f() -> impl DerefMut<Target = u8> {
fn f() -> impl Deref + DerefMut<Target = u8> {
Box::new(123)
}
}
impl SomeTrait for SomeStruct {
// Check that it works in trait impls.
fn f() -> impl DerefMut<Target = u8> {
fn f() -> impl Deref + DerefMut<Target = u8> {
Box::new(42)
}
}

View File

@ -86,6 +86,18 @@ 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> {
| ^^^^^
|
@ -95,5 +107,17 @@ LL - fn f() -> impl Deref + DerefMut<Target = u8> {
LL + fn f() -> impl DerefMut<Target = u8> {
|
error: aborting due to 8 previous errors
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