@@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(
28
28
&& let PatKind :: Binding ( _, pat_hir_id, _, _) = pat. kind
29
29
&& path_to_local_id ( let_expr, pat_hir_id)
30
30
// 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, pats , _) = let_pat. kind
32
32
&& let Res :: Def ( DefKind :: Ctor ( ..) , ctor_id) = cx. qpath_res ( qpath, let_pat. hir_id )
33
33
&& let Some ( variant_id) = cx. tcx . opt_parent ( ctor_id)
34
34
&& let some_ctor = cx. tcx . lang_items ( ) . option_some_variant ( ) == Some ( variant_id)
@@ -39,9 +39,13 @@ pub(super) fn check<'tcx>(
39
39
&& msrv. meets ( cx, msrvs:: ITER_FLATTEN )
40
40
{
41
41
let if_let_type = if some_ctor { "Some" } else { "Ok" } ;
42
+ let has_nested_tuple_struct = contains_nested_tuple_struct ( pats) ;
42
43
// Prepare the error message
43
- let msg =
44
- format ! ( "unnecessary `if let` since only the `{if_let_type}` variant of the iterator element is used" ) ;
44
+ let msg = if has_nested_tuple_struct {
45
+ "manual flattening detected" . to_string ( )
46
+ } else {
47
+ format ! ( "unnecessary `if let` since only the `{if_let_type}` variant of the iterator element is used" )
48
+ } ;
45
49
46
50
// Prepare the help message
47
51
let mut applicability = Applicability :: MaybeIncorrect ;
@@ -60,9 +64,15 @@ pub(super) fn check<'tcx>(
60
64
// case, it will be shown in the extra `help` message at the end, which is why the first
61
65
// `help_msg` needs to refer to the correct relative position of the suggestion.
62
66
let help_msg = if sugg. contains ( '\n' ) {
63
- "remove the `if let` statement in the for loop and then..."
67
+ if has_nested_tuple_struct {
68
+ format ! ( "remove the outer `{if_let_type}` variant in the for loop and then..." )
69
+ } else {
70
+ "remove the `if let` statement in the for loop and then..." . to_string ( )
71
+ }
72
+ } else if has_nested_tuple_struct {
73
+ format ! ( "...and remove the outer `{if_let_type}` variant in the for loop" )
64
74
} else {
65
- "...and remove the `if let` statement in the for loop"
75
+ "...and remove the `if let` statement in the for loop" . to_string ( )
66
76
} ;
67
77
68
78
span_lint_and_then ( cx, MANUAL_FLATTEN , span, msg, |diag| {
@@ -71,3 +81,19 @@ pub(super) fn check<'tcx>(
71
81
} ) ;
72
82
}
73
83
}
84
+
85
+ fn contains_nested_tuple_struct ( pats : & [ Pat < ' _ > ] ) -> bool {
86
+ for pat in pats {
87
+ match pat. kind {
88
+ PatKind :: TupleStruct ( _, _, _) => {
89
+ return true ;
90
+ } ,
91
+ PatKind :: Tuple ( pats, _) => {
92
+ return contains_nested_tuple_struct ( pats) ;
93
+ } ,
94
+ _ => { } ,
95
+ }
96
+ }
97
+
98
+ false
99
+ }
0 commit comments