From db62821c03ed89404891499fb0840b0b7dc78e11 Mon Sep 17 00:00:00 2001 From: tamaron Date: Thu, 24 Feb 2022 00:16:24 +0900 Subject: [PATCH 1/2] fix --- clippy_lints/src/eta_reduction.rs | 8 ++++++++ tests/ui/eta.fixed | 19 +++++++++++++++++++ tests/ui/eta.rs | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 263bff4873ca..687e56e57f45 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -10,6 +10,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind, Param, PatKind, Unsafety}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; +use rustc_middle::ty::binding::BindingMode; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -169,11 +170,18 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_ if params.len() != call_args.len() { return false; } + let binding_modes = cx.typeck_results().pat_binding_modes(); std::iter::zip(params, call_args).all(|(param, arg)| { match param.pat.kind { PatKind::Binding(_, id, ..) if path_to_local_id(arg, id) => {}, _ => return false, } + // checks that parameters are not bound as `ref` + //dbg!(binding_modes.get(param.pat.hir_id)); + if let Some(BindingMode::BindByReference(_)) = binding_modes.get(param.pat.hir_id) { + return false; + } + match *cx.typeck_results().expr_adjustments(arg) { [] => true, [ diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index 618f80cdcf84..5aedbea381f2 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -256,3 +256,22 @@ fn arc_fp() { (0..5).map(|n| arc(n)); Some(4).map(|n| ref_arc(n)); } + +// #8460 Don't replace closures with params bounded as `ref` +mod bind_by_ref { + struct A; + struct B; + + impl From<&A> for B { + fn from(A: &A) -> Self { + B + } + } + + fn test() { + // should not lint + Some(A).map(|a| B::from(&a)); + // should not lint + Some(A).map(|ref a| B::from(a)); + } +} diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index a759e6eb514b..5fdf7fb97716 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -256,3 +256,22 @@ fn arc_fp() { (0..5).map(|n| arc(n)); Some(4).map(|n| ref_arc(n)); } + +// #8460 Don't replace closures with params bounded as `ref` +mod bind_by_ref { + struct A; + struct B; + + impl From<&A> for B { + fn from(A: &A) -> Self { + B + } + } + + fn test() { + // should not lint + Some(A).map(|a| B::from(&a)); + // should not lint + Some(A).map(|ref a| B::from(a)); + } +} From 31b49b0be8e1153da13be71dcc9d6bff888217e2 Mon Sep 17 00:00:00 2001 From: tamaron Date: Thu, 24 Feb 2022 00:25:07 +0900 Subject: [PATCH 2/2] fix typo --- clippy_lints/src/eta_reduction.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 687e56e57f45..d23c0c225e19 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -176,8 +176,7 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_ PatKind::Binding(_, id, ..) if path_to_local_id(arg, id) => {}, _ => return false, } - // checks that parameters are not bound as `ref` - //dbg!(binding_modes.get(param.pat.hir_id)); + // checks that parameters are not bound as `ref` or `ref mut` if let Some(BindingMode::BindByReference(_)) = binding_modes.get(param.pat.hir_id) { return false; }