Skip to content

Commit 983e5b8

Browse files
committed
Auto merge of #7566 - dswij:manual-flatten-use, r=xFrednet
Check expr usage for `manual_flatten` Fixes #6784 Fixes #7538 `manual_flatten` should not trigger when `if let` match expression will be used. changelog: [`manual_flatten`] checks for expr usage after `if let`
2 parents 3f0c977 + a09bc1b commit 983e5b8

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

clippy_lints/src/loops/manual_flatten.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::utils::make_iterator_snippet;
22
use super::MANUAL_FLATTEN;
33
use clippy_utils::diagnostics::span_lint_and_then;
4+
use clippy_utils::visitors::LocalUsedVisitor;
45
use clippy_utils::{is_lang_ctor, path_to_local_id};
56
use if_chain::if_chain;
67
use rustc_errors::Applicability;
@@ -37,16 +38,18 @@ pub(super) fn check<'tcx>(
3738
if_chain! {
3839
if let Some(inner_expr) = inner_expr;
3940
if let ExprKind::Match(
40-
match_expr, match_arms, MatchSource::IfLetDesugar{ contains_else_clause: false }
41+
match_expr, [true_arm, _else_arm], MatchSource::IfLetDesugar{ contains_else_clause: false }
4142
) = inner_expr.kind;
4243
// Ensure match_expr in `if let` statement is the same as the pat from the for-loop
4344
if let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind;
4445
if path_to_local_id(match_expr, pat_hir_id);
4546
// Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result`
46-
if let PatKind::TupleStruct(ref qpath, _, _) = match_arms[0].pat.kind;
47+
if let PatKind::TupleStruct(ref qpath, _, _) = true_arm.pat.kind;
4748
let some_ctor = is_lang_ctor(cx, qpath, OptionSome);
4849
let ok_ctor = is_lang_ctor(cx, qpath, ResultOk);
4950
if some_ctor || ok_ctor;
51+
// Ensure epxr in `if let` is not used afterwards
52+
if !LocalUsedVisitor::new(cx, pat_hir_id).check_arm(true_arm);
5053
then {
5154
let if_let_type = if some_ctor { "Some" } else { "Ok" };
5255
// Prepare the error message

tests/ui/manual_flatten.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,19 @@ fn main() {
9191
}
9292
}
9393

94+
struct Test {
95+
a: usize,
96+
}
97+
98+
let mut vec_of_struct = [Some(Test { a: 1 }), None];
99+
100+
// Usage of `if let` expression should not trigger lint
101+
for n in vec_of_struct.iter_mut() {
102+
if let Some(z) = n {
103+
*n = None;
104+
}
105+
}
106+
94107
// Using manual flatten should not trigger the lint
95108
for n in vec![Some(1), Some(2), Some(3)].iter().flatten() {
96109
println!("{}", n);

0 commit comments

Comments
 (0)