]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/eta_reduction.rs
Auto merge of #4551 - mikerite:fix-ice-reporting, r=llogiq
[rust.git] / clippy_lints / src / eta_reduction.rs
index b12e3167997acaeeedefd98e11fe7aecfff16853..485a29ed3d89c80e77874965065a7278ee493a0b 100644 (file)
@@ -6,7 +6,9 @@
 use rustc::{declare_lint_pass, declare_tool_lint};
 use rustc_errors::Applicability;
 
-use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then, type_is_unsafe_function};
+use crate::utils::{
+    implements_trait, is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then, type_is_unsafe_function,
+};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for closures which just call another function where
@@ -152,7 +154,9 @@ fn get_ufcs_type_name(
     let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id);
 
     if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) {
-        if match_borrow_depth(expected_type_of_self, &actual_type_of_self) {
+        if match_borrow_depth(expected_type_of_self, &actual_type_of_self)
+            && implements_trait(cx, actual_type_of_self, trait_id, &[])
+        {
             return Some(cx.tcx.def_path_str(trait_id));
         }
     }
@@ -168,7 +172,7 @@ fn get_ufcs_type_name(
 
 fn match_borrow_depth(lhs: Ty<'_>, rhs: Ty<'_>) -> bool {
     match (&lhs.sty, &rhs.sty) {
-        (ty::Ref(_, t1, _), ty::Ref(_, t2, _)) => match_borrow_depth(&t1, &t2),
+        (ty::Ref(_, t1, mut1), ty::Ref(_, t2, mut2)) => mut1 == mut2 && match_borrow_depth(&t1, &t2),
         (l, r) => match (l, r) {
             (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false,
             (_, _) => true,
@@ -183,9 +187,8 @@ fn match_types(lhs: Ty<'_>, rhs: Ty<'_>) -> bool {
         | (ty::Int(_), ty::Int(_))
         | (ty::Uint(_), ty::Uint(_))
         | (ty::Str, ty::Str) => true,
-        (ty::Ref(_, t1, _), ty::Ref(_, t2, _))
-        | (ty::Array(t1, _), ty::Array(t2, _))
-        | (ty::Slice(t1), ty::Slice(t2)) => match_types(t1, t2),
+        (ty::Ref(_, t1, mut1), ty::Ref(_, t2, mut2)) => mut1 == mut2 && match_types(t1, t2),
+        (ty::Array(t1, _), ty::Array(t2, _)) | (ty::Slice(t1), ty::Slice(t2)) => match_types(t1, t2),
         (ty::Adt(def1, _), ty::Adt(def2, _)) => def1 == def2,
         (_, _) => false,
     }
@@ -199,7 +202,10 @@ fn get_type_name(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> String {
     }
 }
 
-fn compare_inputs(closure_inputs: &mut dyn Iterator<Item = &Arg>, call_args: &mut dyn Iterator<Item = &Expr>) -> bool {
+fn compare_inputs(
+    closure_inputs: &mut dyn Iterator<Item = &Param>,
+    call_args: &mut dyn Iterator<Item = &Expr>,
+) -> bool {
     for (closure_input, function_arg) in closure_inputs.zip(call_args) {
         if let PatKind::Binding(_, _, ident, _) = closure_input.pat.node {
             // XXXManishearth Should I be checking the binding mode here?