Skip to content

Commit db62821

Browse files
committed
fix
1 parent 7f8760a commit db62821

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

clippy_lints/src/eta_reduction.rs

+8
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,18 @@ 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`
180+
//dbg!(binding_modes.get(param.pat.hir_id));
181+
if let Some(BindingMode::BindByReference(_)) = binding_modes.get(param.pat.hir_id) {
182+
return false;
183+
}
184+
177185
match *cx.typeck_results().expr_adjustments(arg) {
178186
[] => true,
179187
[

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)