Skip to content

Commit 042892a

Browse files
committedFeb 23, 2022
Auto merge of rust-lang#8466 - tamaroning:fix_reduntant_closure, r=Manishearth
False positive redundant_closure when using ref pattern in closure params fixes rust-lang#8460 Fixed [redundant_closure] so that closures of which params bound as `ref` or `ref mut ` doesn't trigger the lint. (e.g. `|ref x| some_expr` doesn't trigger the lint.) changelog: none
2 parents 7f8760a + 31b49b0 commit 042892a

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed
 

‎clippy_lints/src/eta_reduction.rs

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir::def_id::DefId;
1010
use rustc_hir::{Expr, ExprKind, Param, PatKind, Unsafety};
1111
use rustc_lint::{LateContext, LateLintPass};
1212
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
13+
use rustc_middle::ty::binding::BindingMode;
1314
use rustc_middle::ty::subst::Subst;
1415
use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable};
1516
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -169,11 +170,17 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_
169170
if params.len() != call_args.len() {
170171
return false;
171172
}
173+
let binding_modes = cx.typeck_results().pat_binding_modes();
172174
std::iter::zip(params, call_args).all(|(param, arg)| {
173175
match param.pat.kind {
174176
PatKind::Binding(_, id, ..) if path_to_local_id(arg, id) => {},
175177
_ => return false,
176178
}
179+
// checks that parameters are not bound as `ref` or `ref mut`
180+
if let Some(BindingMode::BindByReference(_)) = binding_modes.get(param.pat.hir_id) {
181+
return false;
182+
}
183+
177184
match *cx.typeck_results().expr_adjustments(arg) {
178185
[] => true,
179186
[

‎tests/ui/eta.fixed

+19
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,22 @@ fn arc_fp() {
256256
(0..5).map(|n| arc(n));
257257
Some(4).map(|n| ref_arc(n));
258258
}
259+
260+
// #8460 Don't replace closures with params bounded as `ref`
261+
mod bind_by_ref {
262+
struct A;
263+
struct B;
264+
265+
impl From<&A> for B {
266+
fn from(A: &A) -> Self {
267+
B
268+
}
269+
}
270+
271+
fn test() {
272+
// should not lint
273+
Some(A).map(|a| B::from(&a));
274+
// should not lint
275+
Some(A).map(|ref a| B::from(a));
276+
}
277+
}

‎tests/ui/eta.rs

+19
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,22 @@ fn arc_fp() {
256256
(0..5).map(|n| arc(n));
257257
Some(4).map(|n| ref_arc(n));
258258
}
259+
260+
// #8460 Don't replace closures with params bounded as `ref`
261+
mod bind_by_ref {
262+
struct A;
263+
struct B;
264+
265+
impl From<&A> for B {
266+
fn from(A: &A) -> Self {
267+
B
268+
}
269+
}
270+
271+
fn test() {
272+
// should not lint
273+
Some(A).map(|a| B::from(&a));
274+
// should not lint
275+
Some(A).map(|ref a| B::from(a));
276+
}
277+
}

0 commit comments

Comments
 (0)
Please sign in to comment.