Skip to content

Commit 3927a61

Browse files
authored
[manual_flatten]: Fix with nested Some or Ok pattern (#14846)
changelog: [`manual_flatten`]: fix with nested `Some` or `Ok` pattern fixes #6776
2 parents b719f99 + 816fa0a commit 3927a61

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

clippy_lints/src/loops/manual_flatten.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::utils::make_iterator_snippet;
33
use clippy_utils::diagnostics::span_lint_and_then;
44
use clippy_utils::msrvs::{self, Msrv};
55
use clippy_utils::visitors::is_local_used;
6-
use clippy_utils::{higher, path_to_local_id, peel_blocks_with_stmt};
6+
use clippy_utils::{higher, is_refutable, path_to_local_id, peel_blocks_with_stmt};
77
use rustc_errors::Applicability;
88
use rustc_hir::def::{DefKind, Res};
99
use rustc_hir::{Expr, Pat, PatKind};
@@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(
2828
&& let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind
2929
&& path_to_local_id(let_expr, pat_hir_id)
3030
// Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result`
31-
&& let PatKind::TupleStruct(ref qpath, _, _) = let_pat.kind
31+
&& let PatKind::TupleStruct(ref qpath, [inner_pat], _) = let_pat.kind
3232
&& let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, let_pat.hir_id)
3333
&& let Some(variant_id) = cx.tcx.opt_parent(ctor_id)
3434
&& let some_ctor = cx.tcx.lang_items().option_some_variant() == Some(variant_id)
@@ -37,6 +37,7 @@ pub(super) fn check<'tcx>(
3737
// Ensure expr in `if let` is not used afterwards
3838
&& !is_local_used(cx, if_then, pat_hir_id)
3939
&& msrv.meets(cx, msrvs::ITER_FLATTEN)
40+
&& !is_refutable(cx, inner_pat)
4041
{
4142
let if_let_type = if some_ctor { "Some" } else { "Ok" };
4243
// Prepare the error message

tests/ui/manual_flatten.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ fn main() {
123123
println!("{}", n);
124124
}
125125

126+
// Using nested `Some` pattern should not trigger the lint
127+
for n in vec![Some((1, Some(2)))] {
128+
if let Some((_, Some(n))) = n {
129+
println!("{}", n);
130+
}
131+
}
132+
126133
run_unformatted_tests();
127134
}
128135

tests/ui/manual_flatten.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ LL | | }
178178
| |_________^
179179

180180
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
181-
--> tests/ui/manual_flatten.rs:132:5
181+
--> tests/ui/manual_flatten.rs:139:5
182182
|
183183
LL | / for n in vec![
184184
LL | |
@@ -189,7 +189,7 @@ LL | | }
189189
| |_____^
190190
|
191191
help: remove the `if let` statement in the for loop and then...
192-
--> tests/ui/manual_flatten.rs:139:9
192+
--> tests/ui/manual_flatten.rs:146:9
193193
|
194194
LL | / if let Some(n) = n {
195195
LL | | println!("{:?}", n);

0 commit comments

Comments
 (0)