Skip to content

Commit

Permalink
Auto merge of #12155 - GuillaumeGomez:fix-9961, r=blyxyas
Browse files Browse the repository at this point in the history
Correctly handle type relative in trait_duplication_in_bounds lint

Fixes #9961.

The generic bounds were not correctly checked and left out `QPath::TypeRelative`, making different bounds look the same and generating invalid errors (and fix).

r? `@blyxyas`

changelog: [`trait_duplication_in_bounds`]: Correctly handle type relative.
  • Loading branch information
bors committed Jan 17, 2024
2 parents e27ebf2 + 7217c22 commit 2067fe4
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 6 deletions.
14 changes: 10 additions & 4 deletions clippy_lints/src/trait_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,14 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'
}
}

fn get_ty_res(ty: Ty<'_>) -> Option<Res> {
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(
Expand All @@ -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
}))
Expand Down
31 changes: 30 additions & 1 deletion tests/ui/trait_duplication_in_bounds.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
fn is_base(&self);
}

trait Derived<B: Proj>: Base<B::S> + Base<()> {
fn is_derived(&self);
}

fn f<P: Proj>(obj: &dyn Derived<P>) {
obj.is_derived();
Base::<P::S>::is_base(obj);
Base::<()>::is_base(obj);
}

fn main() {
let _x: fn(_) = f::<()>;
let _x: fn(_) = f::<i32>;
}
31 changes: 30 additions & 1 deletion tests/ui/trait_duplication_in_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
fn is_base(&self);
}

trait Derived<B: Proj>: Base<B::S> + Base<()> {
fn is_derived(&self);
}

fn f<P: Proj>(obj: &dyn Derived<P>) {
obj.is_derived();
Base::<P::S>::is_base(obj);
Base::<()>::is_base(obj);
}

fn main() {
let _x: fn(_) = f::<()>;
let _x: fn(_) = f::<i32>;
}

0 comments on commit 2067fe4

Please sign in to comment.