mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 17:53:56 +00:00
Auto merge of #6962 - TaKO8Ki:fix-false-positive-in-manual-flatten, r=llogiq
Fix false positive in `manual_flatten` This pull request fixes false positive in `manual_flatten` in case using a slice of references . closes: #6893 changelog: fix false positive in `manual_flatten`
This commit is contained in:
commit
917b538c68
@ -6,6 +6,7 @@ use if_chain::if_chain;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, StmtKind};
|
use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, StmtKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_middle::ty;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
|
|
||||||
/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the
|
/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the
|
||||||
@ -54,6 +55,13 @@ pub(super) fn check<'tcx>(
|
|||||||
// Prepare the help message
|
// Prepare the help message
|
||||||
let mut applicability = Applicability::MaybeIncorrect;
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
let arg_snippet = make_iterator_snippet(cx, arg, &mut applicability);
|
let arg_snippet = make_iterator_snippet(cx, arg, &mut applicability);
|
||||||
|
let copied = match cx.typeck_results().expr_ty(match_expr).kind() {
|
||||||
|
ty::Ref(_, inner, _) => match inner.kind() {
|
||||||
|
ty::Ref(..) => ".copied()",
|
||||||
|
_ => ""
|
||||||
|
}
|
||||||
|
_ => ""
|
||||||
|
};
|
||||||
|
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
@ -61,7 +69,7 @@ pub(super) fn check<'tcx>(
|
|||||||
span,
|
span,
|
||||||
&msg,
|
&msg,
|
||||||
|diag| {
|
|diag| {
|
||||||
let sugg = format!("{}.flatten()", arg_snippet);
|
let sugg = format!("{}{}.flatten()", arg_snippet, copied);
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
arg.span,
|
arg.span,
|
||||||
"try",
|
"try",
|
||||||
|
@ -5,8 +5,7 @@ use rustc_ast::ast;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_middle::ty::Ty;
|
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
pub(super) fn derefs_to_slice<'tcx>(
|
pub(super) fn derefs_to_slice<'tcx>(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![warn(clippy::manual_flatten)]
|
#![warn(clippy::manual_flatten)]
|
||||||
|
#![allow(clippy::useless_vec)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Test for loop over implicitly adjusted `Iterator` with `if let` expression
|
// Test for loop over implicitly adjusted `Iterator` with `if let` expression
|
||||||
@ -69,6 +70,27 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vec_of_ref = vec![&Some(1)];
|
||||||
|
for n in &vec_of_ref {
|
||||||
|
if let Some(n) = n {
|
||||||
|
println!("{:?}", n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let vec_of_ref = &vec_of_ref;
|
||||||
|
for n in vec_of_ref {
|
||||||
|
if let Some(n) = n {
|
||||||
|
println!("{:?}", n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let slice_of_ref = &[&Some(1)];
|
||||||
|
for n in slice_of_ref {
|
||||||
|
if let Some(n) = n {
|
||||||
|
println!("{:?}", n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Using manual flatten should not trigger the lint
|
// Using manual flatten should not trigger the lint
|
||||||
for n in vec![Some(1), Some(2), Some(3)].iter().flatten() {
|
for n in vec![Some(1), Some(2), Some(3)].iter().flatten() {
|
||||||
println!("{}", n);
|
println!("{}", n);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||||
--> $DIR/manual_flatten.rs:6:5
|
--> $DIR/manual_flatten.rs:7:5
|
||||||
|
|
|
|
||||||
LL | for n in x {
|
LL | for n in x {
|
||||||
| ^ - help: try: `x.into_iter().flatten()`
|
| ^ - help: try: `x.into_iter().flatten()`
|
||||||
@ -13,7 +13,7 @@ LL | | }
|
|||||||
|
|
|
|
||||||
= note: `-D clippy::manual-flatten` implied by `-D warnings`
|
= note: `-D clippy::manual-flatten` implied by `-D warnings`
|
||||||
help: ...and remove the `if let` statement in the for loop
|
help: ...and remove the `if let` statement in the for loop
|
||||||
--> $DIR/manual_flatten.rs:7:9
|
--> $DIR/manual_flatten.rs:8:9
|
||||||
|
|
|
|
||||||
LL | / if let Some(y) = n {
|
LL | / if let Some(y) = n {
|
||||||
LL | | println!("{}", y);
|
LL | | println!("{}", y);
|
||||||
@ -21,7 +21,7 @@ LL | | }
|
|||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
||||||
--> $DIR/manual_flatten.rs:14:5
|
--> $DIR/manual_flatten.rs:15:5
|
||||||
|
|
|
|
||||||
LL | for n in y.clone() {
|
LL | for n in y.clone() {
|
||||||
| ^ --------- help: try: `y.clone().into_iter().flatten()`
|
| ^ --------- help: try: `y.clone().into_iter().flatten()`
|
||||||
@ -34,7 +34,7 @@ LL | | }
|
|||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
|
||||||
help: ...and remove the `if let` statement in the for loop
|
help: ...and remove the `if let` statement in the for loop
|
||||||
--> $DIR/manual_flatten.rs:15:9
|
--> $DIR/manual_flatten.rs:16:9
|
||||||
|
|
|
|
||||||
LL | / if let Ok(n) = n {
|
LL | / if let Ok(n) = n {
|
||||||
LL | | println!("{}", n);
|
LL | | println!("{}", n);
|
||||||
@ -42,7 +42,7 @@ LL | | };
|
|||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
||||||
--> $DIR/manual_flatten.rs:21:5
|
--> $DIR/manual_flatten.rs:22:5
|
||||||
|
|
|
|
||||||
LL | for n in &y {
|
LL | for n in &y {
|
||||||
| ^ -- help: try: `y.iter().flatten()`
|
| ^ -- help: try: `y.iter().flatten()`
|
||||||
@ -55,7 +55,7 @@ LL | | }
|
|||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
|
||||||
help: ...and remove the `if let` statement in the for loop
|
help: ...and remove the `if let` statement in the for loop
|
||||||
--> $DIR/manual_flatten.rs:22:9
|
--> $DIR/manual_flatten.rs:23:9
|
||||||
|
|
|
|
||||||
LL | / if let Ok(n) = n {
|
LL | / if let Ok(n) = n {
|
||||||
LL | | println!("{}", n);
|
LL | | println!("{}", n);
|
||||||
@ -63,7 +63,7 @@ LL | | }
|
|||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
||||||
--> $DIR/manual_flatten.rs:31:5
|
--> $DIR/manual_flatten.rs:32:5
|
||||||
|
|
|
|
||||||
LL | for n in z {
|
LL | for n in z {
|
||||||
| ^ - help: try: `z.into_iter().flatten()`
|
| ^ - help: try: `z.into_iter().flatten()`
|
||||||
@ -76,7 +76,7 @@ LL | | }
|
|||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
|
||||||
help: ...and remove the `if let` statement in the for loop
|
help: ...and remove the `if let` statement in the for loop
|
||||||
--> $DIR/manual_flatten.rs:32:9
|
--> $DIR/manual_flatten.rs:33:9
|
||||||
|
|
|
|
||||||
LL | / if let Ok(n) = n {
|
LL | / if let Ok(n) = n {
|
||||||
LL | | println!("{}", n);
|
LL | | println!("{}", n);
|
||||||
@ -84,7 +84,7 @@ LL | | }
|
|||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||||
--> $DIR/manual_flatten.rs:40:5
|
--> $DIR/manual_flatten.rs:41:5
|
||||||
|
|
|
|
||||||
LL | for n in z {
|
LL | for n in z {
|
||||||
| ^ - help: try: `z.flatten()`
|
| ^ - help: try: `z.flatten()`
|
||||||
@ -97,12 +97,75 @@ LL | | }
|
|||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
|
||||||
help: ...and remove the `if let` statement in the for loop
|
help: ...and remove the `if let` statement in the for loop
|
||||||
--> $DIR/manual_flatten.rs:41:9
|
--> $DIR/manual_flatten.rs:42:9
|
||||||
|
|
|
|
||||||
LL | / if let Some(m) = n {
|
LL | / if let Some(m) = n {
|
||||||
LL | | println!("{}", m);
|
LL | | println!("{}", m);
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_________^
|
| |_________^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||||
|
--> $DIR/manual_flatten.rs:74:5
|
||||||
|
|
|
||||||
|
LL | for n in &vec_of_ref {
|
||||||
|
| ^ ----------- help: try: `vec_of_ref.iter().copied().flatten()`
|
||||||
|
| _____|
|
||||||
|
| |
|
||||||
|
LL | | if let Some(n) = n {
|
||||||
|
LL | | println!("{:?}", n);
|
||||||
|
LL | | }
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
help: ...and remove the `if let` statement in the for loop
|
||||||
|
--> $DIR/manual_flatten.rs:75:9
|
||||||
|
|
|
||||||
|
LL | / if let Some(n) = n {
|
||||||
|
LL | | println!("{:?}", n);
|
||||||
|
LL | | }
|
||||||
|
| |_________^
|
||||||
|
|
||||||
|
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||||
|
--> $DIR/manual_flatten.rs:81:5
|
||||||
|
|
|
||||||
|
LL | for n in vec_of_ref {
|
||||||
|
| ^ ---------- help: try: `vec_of_ref.into_iter().copied().flatten()`
|
||||||
|
| _____|
|
||||||
|
| |
|
||||||
|
LL | | if let Some(n) = n {
|
||||||
|
LL | | println!("{:?}", n);
|
||||||
|
LL | | }
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
help: ...and remove the `if let` statement in the for loop
|
||||||
|
--> $DIR/manual_flatten.rs:82:9
|
||||||
|
|
|
||||||
|
LL | / if let Some(n) = n {
|
||||||
|
LL | | println!("{:?}", n);
|
||||||
|
LL | | }
|
||||||
|
| |_________^
|
||||||
|
|
||||||
|
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||||
|
--> $DIR/manual_flatten.rs:88:5
|
||||||
|
|
|
||||||
|
LL | for n in slice_of_ref {
|
||||||
|
| ^ ------------ help: try: `slice_of_ref.into_iter().copied().flatten()`
|
||||||
|
| _____|
|
||||||
|
| |
|
||||||
|
LL | | if let Some(n) = n {
|
||||||
|
LL | | println!("{:?}", n);
|
||||||
|
LL | | }
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
help: ...and remove the `if let` statement in the for loop
|
||||||
|
--> $DIR/manual_flatten.rs:89:9
|
||||||
|
|
|
||||||
|
LL | / if let Some(n) = n {
|
||||||
|
LL | | println!("{:?}", n);
|
||||||
|
LL | | }
|
||||||
|
| |_________^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user