about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Uy <ariel.b.uy@gmail.com>2022-07-10 09:39:36 -0700
committerAriel Uy <ariel.b.uy@gmail.com>2022-07-17 11:23:09 -0700
commit8cf39a8c1908709831ab27937a53a2d6d0278ff6 (patch)
tree9825e904535eb86f7f7c159b157e03c2b73bc444
parent58cd01c2fcda07f97efcd908b50e5256cf084593 (diff)
downloadrust-8cf39a8c1908709831ab27937a53a2d6d0278ff6.tar.gz
rust-8cf39a8c1908709831ab27937a53a2d6d0278ff6.zip
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.
-rw-r--r--clippy_lints/src/mismatching_type_param_order.rs24
-rw-r--r--tests/ui/mismatching_type_param_order.rs4
2 files changed, 19 insertions, 9 deletions
diff --git a/clippy_lints/src/mismatching_type_param_order.rs b/clippy_lints/src/mismatching_type_param_order.rs
index d466d54a6ba..8e477cb7179 100644
--- a/clippy_lints/src/mismatching_type_param_order.rs
+++ b/clippy_lints/src/mismatching_type_param_order.rs
@@ -18,6 +18,11 @@ declare_clippy_lint! {
     /// Naming type parameters inconsistently may cause you to refer to the
     /// wrong type parameter.
     ///
+    /// ### Limitations
+    /// This lint only applies to impl blocks with simple generic params, e.g.
+    /// `A`. If there is anything more complicated, such as a tuple, it will be
+    /// ignored.
+    ///
     /// ### Example
     /// ```rust
     /// struct Foo<A, B> {
@@ -53,14 +58,15 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
             if !generic_args.args.is_empty();
             then {
                 // get the name and span of the generic parameters in the Impl
-                let impl_params = generic_args.args.iter()
-                .filter_map(|p|
+                let mut impl_params = Vec::new();
+                for p in generic_args.args.iter() {
                     match p {
                         GenericArg::Type(Ty {kind: TyKind::Path(QPath::Resolved(_, path)), ..}) =>
-                            Some((path.segments[0].ident.to_string(), path.span)),
-                        _ => None,
-                    }
-                );
+                            impl_params.push((path.segments[0].ident.to_string(), path.span)),
+                        GenericArg::Type(_) => return,
+                        _ => (),
+                    };
+                }
 
                 // find the type that the Impl is for
                 // only lint on struct/enum/union for now
@@ -83,8 +89,8 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
                     type_param_names.iter().enumerate().map(|(i, param)| (param, i)).collect();
 
                 let type_name = segment.ident;
-                for (i, (impl_param_name, impl_param_span)) in impl_params.enumerate() {
-                    if mismatch_param_name(i, &impl_param_name, &type_param_names_hashmap) {
+                for (i, (impl_param_name, impl_param_span)) in impl_params.iter().enumerate() {
+                    if mismatch_param_name(i, impl_param_name, &type_param_names_hashmap) {
                         let msg = format!("`{}` has a similarly named generic type parameter `{}` in its declaration, but in a different order",
                                           type_name, impl_param_name);
                         let help = format!("try `{}`, or a name that does not conflict with `{}`'s generic params",
@@ -92,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
                         span_lint_and_help(
                             cx,
                             MISMATCHING_TYPE_PARAM_ORDER,
-                            impl_param_span,
+                            *impl_param_span,
                             &msg,
                             None,
                             &help
diff --git a/tests/ui/mismatching_type_param_order.rs b/tests/ui/mismatching_type_param_order.rs
index 8f286c9304c..8c0da84d8e9 100644
--- a/tests/ui/mismatching_type_param_order.rs
+++ b/tests/ui/mismatching_type_param_order.rs
@@ -57,4 +57,8 @@ fn main() {
         B: Copy,
     {
     }
+
+    // if the types are complicated, do not lint
+    impl<K, V, B> Foo<(K, V), B> {}
+    impl<K, V, A> Foo<(K, V), A> {}
 }