From a7f4d41a7d1aa8547df583bd0239a3e35c740018 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Tue, 26 Feb 2019 12:12:27 +0100 Subject: [PATCH] do not trigger redundant_closure when there is a difference in borrow level between closure parameter and "self" --- clippy_lints/src/eta_reduction.rs | 23 ++++++++++++++--------- tests/ui/eta.rs | 8 ++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 05793f32c6cc..331d1a0ec1dc 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -133,18 +133,13 @@ fn get_ufcs_type_name( let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id).sty; if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) { - //if the method expectes &self, ufcs requires explicit borrowing so closure can't be removed - return match (expected_type_of_self, actual_type_of_self) { - (ty::Ref(_, _, _), ty::Ref(_, _, _)) => Some(cx.tcx.item_path_str(trait_id)), - (l, r) => match (l, r) { - (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => None, - (_, _) => Some(cx.tcx.item_path_str(trait_id)), - }, - }; + if match_borrow_depth(expected_type_of_self, actual_type_of_self) { + return Some(cx.tcx.item_path_str(trait_id)); + } } cx.tcx.impl_of_method(method_def_id).and_then(|_| { - //a type may implicitly implement other types methods (e.g. Deref) + //a type may implicitly implement other type's methods (e.g. Deref) if match_types(expected_type_of_self, actual_type_of_self) { return Some(get_type_name(cx, &actual_type_of_self)); } @@ -152,6 +147,16 @@ fn get_ufcs_type_name( }) } +fn match_borrow_depth(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool { + match (lhs, rhs) { + (ty::Ref(_, t1, _), ty::Ref(_, t2, _)) => match_borrow_depth(&t1.sty, &t2.sty), + (l, r) => match (l, r) { + (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false, + (_, _) => true, + }, + } +} + fn match_types(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool { match (lhs, rhs) { (ty::Bool, ty::Bool) diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 6eeb093eae99..f777939c67d2 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -88,6 +88,14 @@ fn test_redundant_closures_containing_method_calls() { let c = Some(TestStruct { some_ref: &i }) .as_ref() .map(|c| c.to_ascii_uppercase()); + + fn test_different_borrow_levels(t: &[&T]) + where + T: TestTrait, + { + t.iter().filter(|x| x.trait_foo_ref()); + t.iter().map(|x| x.trait_foo_ref()); + } } fn meta(f: F)