From 169e2ab55b490a2b3103372b97a5d315ce8438e7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 16 Jan 2024 12:12:28 +0100 Subject: [PATCH 1/2] Correctly handle type relative in `trait_duplication_in_bounds` lint --- clippy_lints/src/trait_bounds.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index e4054393d0ad..768623b5d034 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -390,6 +390,14 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &' } } +fn get_ty_res(ty: Ty<'_>) -> Option { + match ty.kind { + TyKind::Path(QPath::Resolved(_, path)) => Some(path.res), + TyKind::Path(QPath::TypeRelative(ty, _)) => get_ty_res(*ty), + _ => None, + } +} + // FIXME: ComparableTraitRef does not support nested bounds needed for associated_type_bounds fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef { ComparableTraitRef( @@ -401,10 +409,8 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef { .filter_map(|segment| { // get trait bound type arguments Some(segment.args?.args.iter().filter_map(|arg| { - if let GenericArg::Type(ty) = arg - && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind - { - return Some(path.res); + if let GenericArg::Type(ty) = arg { + return get_ty_res(**ty); } None })) From 7217c22f697db917336b1eb21bee30020c0fc97b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 16 Jan 2024 12:13:15 +0100 Subject: [PATCH 2/2] Update `trait_duplication_in_bounds.rs` ui test to add regression for ##9961 --- tests/ui/trait_duplication_in_bounds.fixed | 31 +++++++++++++++++++++- tests/ui/trait_duplication_in_bounds.rs | 31 +++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed index 4fca29698e06..7e2663d734f6 100644 --- a/tests/ui/trait_duplication_in_bounds.fixed +++ b/tests/ui/trait_duplication_in_bounds.fixed @@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send)) { unimplemented!(); } -fn main() {} +trait Proj { + type S; +} + +impl Proj for () { + type S = (); +} + +impl Proj for i32 { + type S = i32; +} + +trait Base { + fn is_base(&self); +} + +trait Derived: Base + Base<()> { + fn is_derived(&self); +} + +fn f(obj: &dyn Derived

) { + obj.is_derived(); + Base::::is_base(obj); + Base::<()>::is_base(obj); +} + +fn main() { + let _x: fn(_) = f::<()>; + let _x: fn(_) = f::; +} diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs index f67c8e35ed4c..fede1671a436 100644 --- a/tests/ui/trait_duplication_in_bounds.rs +++ b/tests/ui/trait_duplication_in_bounds.rs @@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { unimplemented!(); } -fn main() {} +trait Proj { + type S; +} + +impl Proj for () { + type S = (); +} + +impl Proj for i32 { + type S = i32; +} + +trait Base { + fn is_base(&self); +} + +trait Derived: Base + Base<()> { + fn is_derived(&self); +} + +fn f(obj: &dyn Derived

) { + obj.is_derived(); + Base::::is_base(obj); + Base::<()>::is_base(obj); +} + +fn main() { + let _x: fn(_) = f::<()>; + let _x: fn(_) = f::; +}