Skip to content

Commit 2067fe4

Browse files
committed
Auto merge of #12155 - GuillaumeGomez:fix-9961, r=blyxyas
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.
2 parents e27ebf2 + 7217c22 commit 2067fe4

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

clippy_lints/src/trait_bounds.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,14 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'
390390
}
391391
}
392392

393+
fn get_ty_res(ty: Ty<'_>) -> Option<Res> {
394+
match ty.kind {
395+
TyKind::Path(QPath::Resolved(_, path)) => Some(path.res),
396+
TyKind::Path(QPath::TypeRelative(ty, _)) => get_ty_res(*ty),
397+
_ => None,
398+
}
399+
}
400+
393401
// FIXME: ComparableTraitRef does not support nested bounds needed for associated_type_bounds
394402
fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
395403
ComparableTraitRef(
@@ -401,10 +409,8 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
401409
.filter_map(|segment| {
402410
// get trait bound type arguments
403411
Some(segment.args?.args.iter().filter_map(|arg| {
404-
if let GenericArg::Type(ty) = arg
405-
&& let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
406-
{
407-
return Some(path.res);
412+
if let GenericArg::Type(ty) = arg {
413+
return get_ty_res(**ty);
408414
}
409415
None
410416
}))

tests/ui/trait_duplication_in_bounds.fixed

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send)) {
118118
unimplemented!();
119119
}
120120

121-
fn main() {}
121+
trait Proj {
122+
type S;
123+
}
124+
125+
impl Proj for () {
126+
type S = ();
127+
}
128+
129+
impl Proj for i32 {
130+
type S = i32;
131+
}
132+
133+
trait Base<T> {
134+
fn is_base(&self);
135+
}
136+
137+
trait Derived<B: Proj>: Base<B::S> + Base<()> {
138+
fn is_derived(&self);
139+
}
140+
141+
fn f<P: Proj>(obj: &dyn Derived<P>) {
142+
obj.is_derived();
143+
Base::<P::S>::is_base(obj);
144+
Base::<()>::is_base(obj);
145+
}
146+
147+
fn main() {
148+
let _x: fn(_) = f::<()>;
149+
let _x: fn(_) = f::<i32>;
150+
}

tests/ui/trait_duplication_in_bounds.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
118118
unimplemented!();
119119
}
120120

121-
fn main() {}
121+
trait Proj {
122+
type S;
123+
}
124+
125+
impl Proj for () {
126+
type S = ();
127+
}
128+
129+
impl Proj for i32 {
130+
type S = i32;
131+
}
132+
133+
trait Base<T> {
134+
fn is_base(&self);
135+
}
136+
137+
trait Derived<B: Proj>: Base<B::S> + Base<()> {
138+
fn is_derived(&self);
139+
}
140+
141+
fn f<P: Proj>(obj: &dyn Derived<P>) {
142+
obj.is_derived();
143+
Base::<P::S>::is_base(obj);
144+
Base::<()>::is_base(obj);
145+
}
146+
147+
fn main() {
148+
let _x: fn(_) = f::<()>;
149+
let _x: fn(_) = f::<i32>;
150+
}

0 commit comments

Comments
 (0)