@@ -5,7 +5,7 @@ use clippy_utils::ty::is_type_diagnostic_item;
5
5
use clippy_utils:: { eq_expr_value, get_parent_expr, higher, is_else_clause, is_lang_ctor, peel_blocks_with_stmt} ;
6
6
use rustc_errors:: Applicability ;
7
7
use rustc_hir:: LangItem :: OptionNone ;
8
- use rustc_hir:: { Arm , BindingAnnotation , Expr , ExprKind , Pat , PatKind , Path , PathSegment , QPath , UnOp } ;
8
+ use rustc_hir:: { Arm , BindingAnnotation , Expr , ExprKind , Pat , PatKind , Path , PathSegment , QPath } ;
9
9
use rustc_lint:: LateContext ;
10
10
use rustc_span:: sym;
11
11
@@ -21,7 +21,7 @@ pub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
21
21
if !eq_expr_value ( cx, ex, ret_expr) {
22
22
return ;
23
23
}
24
- } else if !pat_same_as_expr ( arm. pat , arm. body ) {
24
+ } else if !pat_same_as_expr ( arm. pat , peel_blocks_with_stmt ( arm. body ) ) {
25
25
return ;
26
26
}
27
27
}
@@ -92,6 +92,9 @@ fn check_if_let(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool {
92
92
93
93
if matches ! ( if_else. kind, ExprKind :: Block ( ..) ) {
94
94
let else_expr = peel_blocks_with_stmt ( if_else) ;
95
+ if matches ! ( else_expr. kind, ExprKind :: Block ( ..) ) {
96
+ return false ;
97
+ }
95
98
let ret = strip_return ( else_expr) ;
96
99
let let_expr_ty = cx. typeck_results ( ) . expr_ty ( if_let. let_expr ) ;
97
100
if is_type_diagnostic_item ( cx, let_expr_ty, sym:: Option ) {
@@ -120,40 +123,25 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
120
123
let expr = strip_return ( expr) ;
121
124
match ( & pat. kind , & expr. kind ) {
122
125
// Example: `Some(val) => Some(val)`
123
- (
124
- PatKind :: TupleStruct ( QPath :: Resolved ( _, path) , [ first_pat, ..] , _) ,
125
- ExprKind :: Call ( call_expr, [ first_param, ..] ) ,
126
- ) => {
126
+ ( PatKind :: TupleStruct ( QPath :: Resolved ( _, path) , tuple_params, _) , ExprKind :: Call ( call_expr, call_params) ) => {
127
127
if let ExprKind :: Path ( QPath :: Resolved ( _, call_path) ) = call_expr. kind {
128
- if has_identical_segments ( path. segments , call_path. segments )
129
- && has_same_non_ref_symbol ( first_pat, first_param)
130
- {
131
- return true ;
132
- }
128
+ return has_identical_segments ( path. segments , call_path. segments )
129
+ && has_same_non_ref_symbols ( tuple_params, call_params) ;
133
130
}
134
131
} ,
135
- // Example: `val => val`, or `ref val => *val`
136
- ( PatKind :: Binding ( annot, _, pat_ident, _) , _) => {
137
- let new_expr = if let (
138
- BindingAnnotation :: Ref | BindingAnnotation :: RefMut ,
139
- ExprKind :: Unary ( UnOp :: Deref , operand_expr) ,
140
- ) = ( annot, & expr. kind )
141
- {
142
- operand_expr
143
- } else {
144
- expr
145
- } ;
146
-
147
- if let ExprKind :: Path ( QPath :: Resolved (
132
+ // Example: `val => val`
133
+ (
134
+ PatKind :: Binding ( annot, _, pat_ident, _) ,
135
+ ExprKind :: Path ( QPath :: Resolved (
148
136
_,
149
137
Path {
150
138
segments : [ first_seg, ..] ,
151
139
..
152
140
} ,
153
- ) ) = new_expr . kind
154
- {
155
- return pat_ident . name == first_seg . ident . name ;
156
- }
141
+ ) ) ,
142
+ ) => {
143
+ return ! matches ! ( annot , BindingAnnotation :: Ref | BindingAnnotation :: RefMut )
144
+ && pat_ident . name == first_seg . ident . name ;
157
145
} ,
158
146
// Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
159
147
( PatKind :: Path ( QPath :: Resolved ( _, p_path) ) , ExprKind :: Path ( QPath :: Resolved ( _, e_path) ) ) => {
@@ -183,15 +171,16 @@ fn has_identical_segments(left_segs: &[PathSegment<'_>], right_segs: &[PathSegme
183
171
true
184
172
}
185
173
186
- fn has_same_non_ref_symbol ( pat : & Pat < ' _ > , expr : & Expr < ' _ > ) -> bool {
187
- if_chain ! {
188
- if let PatKind :: Binding ( annot, _, pat_ident, _) = pat. kind;
189
- if !matches!( annot, BindingAnnotation :: Ref | BindingAnnotation :: RefMut ) ;
190
- if let ExprKind :: Path ( QPath :: Resolved ( _, Path { segments: [ first_seg, ..] , .. } ) ) = expr. kind;
191
- then {
192
- return pat_ident. name == first_seg. ident. name;
174
+ fn has_same_non_ref_symbols ( pats : & [ Pat < ' _ > ] , exprs : & [ Expr < ' _ > ] ) -> bool {
175
+ if pats. len ( ) != exprs. len ( ) {
176
+ return false ;
177
+ }
178
+
179
+ for i in 0 ..pats. len ( ) {
180
+ if !pat_same_as_expr ( & pats[ i] , & exprs[ i] ) {
181
+ return false ;
193
182
}
194
183
}
195
184
196
- false
185
+ true
197
186
}
0 commit comments