mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
Handle multiple reference levels into binding type and add more tests
This commit is contained in:
parent
788c9ccc93
commit
ac45a83ad5
7 changed files with 94 additions and 7 deletions
|
@ -50,12 +50,26 @@ pub(super) fn check<'tcx>(
|
||||||
then {
|
then {
|
||||||
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
|
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
|
||||||
Some(search_snippet.replacen('&', "", 1))
|
Some(search_snippet.replacen('&', "", 1))
|
||||||
} else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind {
|
} else if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(closure_arg.pat).kind {
|
||||||
|
// this binding is composed of at least two levels of references, so we need to remove one
|
||||||
|
let binding_type = cx.typeck_results().node_type(binding_id);
|
||||||
|
let innermost_is_ref = if let ty::Ref(_, inner,_) = binding_type.kind() {
|
||||||
|
matches!(inner.kind(), ty::Ref(_, innermost, _) if innermost.is_ref())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
// `find()` provides a reference to the item, but `any` does not,
|
// `find()` provides a reference to the item, but `any` does not,
|
||||||
// so we should fix item usages for suggestion
|
// so we should fix item usages for suggestion
|
||||||
if let Some(closure_sugg) = get_closure_suggestion(cx, search_arg, closure_body) {
|
if let Some(closure_sugg) = get_closure_suggestion(cx, search_arg, closure_body) {
|
||||||
applicability = closure_sugg.applicability;
|
applicability = closure_sugg.applicability;
|
||||||
Some(closure_sugg.suggestion)
|
if innermost_is_ref {
|
||||||
|
Some(closure_sugg.suggestion.replacen('&', "", 1))
|
||||||
|
} else {
|
||||||
|
Some(closure_sugg.suggestion)
|
||||||
|
}
|
||||||
|
} else if innermost_is_ref {
|
||||||
|
Some(search_snippet.replacen('&', "", 1))
|
||||||
} else {
|
} else {
|
||||||
Some(search_snippet.to_string())
|
Some(search_snippet.to_string())
|
||||||
}
|
}
|
||||||
|
@ -230,7 +244,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
|
||||||
// cases where a parent call is using the item
|
// cases where a parent call is using the item
|
||||||
// i.e.: suggest `.contains(&x)` for `.find(|x| [1, 2, 3].contains(x)).is_none()`
|
// i.e.: suggest `.contains(&x)` for `.find(|x| [1, 2, 3].contains(x)).is_none()`
|
||||||
if let Some(parent_expr) = get_parent_expr_for_hir(self.cx, cmt.hir_id) {
|
if let Some(parent_expr) = get_parent_expr_for_hir(self.cx, cmt.hir_id) {
|
||||||
if let ExprKind::Call(..) | ExprKind::MethodCall(..) = parent_expr.kind {
|
if let ExprKind::Call(_, call_args) | ExprKind::MethodCall(_, _, call_args, _) = parent_expr.kind {
|
||||||
let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id);
|
let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id);
|
||||||
let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind();
|
let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind();
|
||||||
|
|
||||||
|
@ -239,8 +253,13 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
|
||||||
let start_span = Span::new(self.next_pos, span.lo(), span.ctxt());
|
let start_span = Span::new(self.next_pos, span.lo(), span.ctxt());
|
||||||
let start_snip =
|
let start_snip =
|
||||||
snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability);
|
snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability);
|
||||||
|
// do not suggest ampersand if the ident is the method caller
|
||||||
self.suggestion_start.push_str(&format!("{}&{}", start_snip, ident_str));
|
let ident_sugg = if !call_args.is_empty() && call_args[0].hir_id == cmt.hir_id {
|
||||||
|
format!("{}{}", start_snip, ident_str)
|
||||||
|
} else {
|
||||||
|
format!("{}&{}", start_snip, ident_str)
|
||||||
|
};
|
||||||
|
self.suggestion_start.push_str(&ident_sugg);
|
||||||
self.next_pos = span.hi();
|
self.next_pos = span.hi();
|
||||||
} else {
|
} else {
|
||||||
self.applicability = Applicability::Unspecified;
|
self.applicability = Applicability::Unspecified;
|
||||||
|
|
|
@ -97,4 +97,15 @@ mod issue7392 {
|
||||||
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
||||||
let _ = !vfoo.iter().any(|sub| sub[1..4].len() == 3);
|
let _ = !vfoo.iter().any(|sub| sub[1..4].len() == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn please(x: &u32) -> bool {
|
||||||
|
*x == 9
|
||||||
|
}
|
||||||
|
|
||||||
|
fn more_projections() {
|
||||||
|
let x = 19;
|
||||||
|
let ppx: &u32 = &x;
|
||||||
|
let _ = ![ppx].iter().any(|ppp_x: &&u32| please(ppp_x));
|
||||||
|
let _ = ![String::from("Hey hey")].iter().any(|s| s.len() == 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,4 +101,15 @@ mod issue7392 {
|
||||||
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
||||||
let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
|
let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn please(x: &u32) -> bool {
|
||||||
|
*x == 9
|
||||||
|
}
|
||||||
|
|
||||||
|
fn more_projections() {
|
||||||
|
let x = 19;
|
||||||
|
let ppx: &u32 = &x;
|
||||||
|
let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();
|
||||||
|
let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,5 +169,17 @@ error: called `is_none()` after searching an `Iterator` with `find`
|
||||||
LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
|
LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
|
||||||
|
|
||||||
error: aborting due to 26 previous errors
|
error: called `is_none()` after searching an `Iterator` with `find`
|
||||||
|
--> $DIR/search_is_some_fixable_none.rs:112:17
|
||||||
|
|
|
||||||
|
LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`
|
||||||
|
|
||||||
|
error: called `is_none()` after searching an `Iterator` with `find`
|
||||||
|
--> $DIR/search_is_some_fixable_none.rs:113:17
|
||||||
|
|
|
||||||
|
LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)`
|
||||||
|
|
||||||
|
error: aborting due to 28 previous errors
|
||||||
|
|
||||||
|
|
|
@ -98,4 +98,15 @@ mod issue7392 {
|
||||||
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
||||||
let _ = vfoo.iter().any(|sub| sub[1..4].len() == 3);
|
let _ = vfoo.iter().any(|sub| sub[1..4].len() == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn please(x: &u32) -> bool {
|
||||||
|
*x == 9
|
||||||
|
}
|
||||||
|
|
||||||
|
fn more_projections() {
|
||||||
|
let x = 19;
|
||||||
|
let ppx: &u32 = &x;
|
||||||
|
let _ = [ppx].iter().any(|ppp_x: &&u32| please(ppp_x));
|
||||||
|
let _ = [String::from("Hey hey")].iter().any(|s| s.len() == 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,4 +100,15 @@ mod issue7392 {
|
||||||
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];
|
||||||
let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
|
let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn please(x: &u32) -> bool {
|
||||||
|
*x == 9
|
||||||
|
}
|
||||||
|
|
||||||
|
fn more_projections() {
|
||||||
|
let x = 19;
|
||||||
|
let ppx: &u32 = &x;
|
||||||
|
let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();
|
||||||
|
let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,5 +160,17 @@ error: called `is_some()` after searching an `Iterator` with `find`
|
||||||
LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
|
LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|sub| sub[1..4].len() == 3)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|sub| sub[1..4].len() == 3)`
|
||||||
|
|
||||||
error: aborting due to 26 previous errors
|
error: called `is_some()` after searching an `Iterator` with `find`
|
||||||
|
--> $DIR/search_is_some_fixable_some.rs:111:30
|
||||||
|
|
|
||||||
|
LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|ppp_x: &&u32| please(ppp_x))`
|
||||||
|
|
||||||
|
error: called `is_some()` after searching an `Iterator` with `find`
|
||||||
|
--> $DIR/search_is_some_fixable_some.rs:112:50
|
||||||
|
|
|
||||||
|
LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s.len() == 2)`
|
||||||
|
|
||||||
|
error: aborting due to 28 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue