Skip to content

Commit 8cf39a8

Browse files
committed
Fix mismatching_type_param_order false positive
Previously was giving false positive when an impl had a nontrivial generic argument such as a tuple. Don't lint on these cases.
1 parent 58cd01c commit 8cf39a8

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

clippy_lints/src/mismatching_type_param_order.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ declare_clippy_lint! {
1818
/// Naming type parameters inconsistently may cause you to refer to the
1919
/// wrong type parameter.
2020
///
21+
/// ### Limitations
22+
/// This lint only applies to impl blocks with simple generic params, e.g.
23+
/// `A`. If there is anything more complicated, such as a tuple, it will be
24+
/// ignored.
25+
///
2126
/// ### Example
2227
/// ```rust
2328
/// struct Foo<A, B> {
@@ -53,14 +58,15 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
5358
if !generic_args.args.is_empty();
5459
then {
5560
// get the name and span of the generic parameters in the Impl
56-
let impl_params = generic_args.args.iter()
57-
.filter_map(|p|
61+
let mut impl_params = Vec::new();
62+
for p in generic_args.args.iter() {
5863
match p {
5964
GenericArg::Type(Ty {kind: TyKind::Path(QPath::Resolved(_, path)), ..}) =>
60-
Some((path.segments[0].ident.to_string(), path.span)),
61-
_ => None,
62-
}
63-
);
65+
impl_params.push((path.segments[0].ident.to_string(), path.span)),
66+
GenericArg::Type(_) => return,
67+
_ => (),
68+
};
69+
}
6470

6571
// find the type that the Impl is for
6672
// only lint on struct/enum/union for now
@@ -83,16 +89,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
8389
type_param_names.iter().enumerate().map(|(i, param)| (param, i)).collect();
8490

8591
let type_name = segment.ident;
86-
for (i, (impl_param_name, impl_param_span)) in impl_params.enumerate() {
87-
if mismatch_param_name(i, &impl_param_name, &type_param_names_hashmap) {
92+
for (i, (impl_param_name, impl_param_span)) in impl_params.iter().enumerate() {
93+
if mismatch_param_name(i, impl_param_name, &type_param_names_hashmap) {
8894
let msg = format!("`{}` has a similarly named generic type parameter `{}` in its declaration, but in a different order",
8995
type_name, impl_param_name);
9096
let help = format!("try `{}`, or a name that does not conflict with `{}`'s generic params",
9197
type_param_names[i], type_name);
9298
span_lint_and_help(
9399
cx,
94100
MISMATCHING_TYPE_PARAM_ORDER,
95-
impl_param_span,
101+
*impl_param_span,
96102
&msg,
97103
None,
98104
&help

tests/ui/mismatching_type_param_order.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,8 @@ fn main() {
5757
B: Copy,
5858
{
5959
}
60+
61+
// if the types are complicated, do not lint
62+
impl<K, V, B> Foo<(K, V), B> {}
63+
impl<K, V, A> Foo<(K, V), A> {}
6064
}

0 commit comments

Comments
 (0)