@@ -78,7 +78,6 @@ impl RetReplacement {
78
78
Self :: Empty => "remove `return`" ,
79
79
Self :: Block => "replace `return` with an empty block" ,
80
80
Self :: Unit => "replace `return` with a unit value" ,
81
-
82
81
}
83
82
}
84
83
}
@@ -161,37 +160,33 @@ impl<'tcx> LateLintPass<'tcx> for Return {
161
160
} else {
162
161
RetReplacement :: Empty
163
162
} ;
164
- check_final_expr ( cx, body. value , Some ( body. value . span ) , replacement) ;
163
+ check_final_expr ( cx, body. value , body. value . span , replacement) ;
165
164
} ,
166
165
FnKind :: ItemFn ( ..) | FnKind :: Method ( ..) => {
167
- if let ExprKind :: Block ( block, _) = body. value . kind {
168
- check_block_return ( cx, block) ;
169
- }
166
+ check_block_return ( cx, & body. value . kind ) ;
170
167
} ,
171
168
}
172
169
}
173
170
}
174
171
175
- fn check_block_return < ' tcx > ( cx : & LateContext < ' tcx > , block : & Block < ' tcx > ) {
176
- if let Some ( expr) = block. expr {
177
- check_final_expr ( cx, expr, Some ( expr. span ) , RetReplacement :: Empty ) ;
178
- } else if let Some ( stmt) = block. stmts . iter ( ) . last ( ) {
179
- match stmt. kind {
180
- StmtKind :: Expr ( expr) | StmtKind :: Semi ( expr) => {
181
- check_final_expr ( cx, expr, Some ( stmt. span ) , RetReplacement :: Empty ) ;
182
- } ,
183
- _ => ( ) ,
172
+ // if `expr` is a block, check if there are needless returns in it
173
+ fn check_block_return < ' tcx > ( cx : & LateContext < ' tcx > , expr_kind : & ExprKind < ' tcx > ) {
174
+ if let ExprKind :: Block ( block, _) = expr_kind {
175
+ if let Some ( block_expr) = block. expr {
176
+ check_final_expr ( cx, block_expr, block_expr. span , RetReplacement :: Empty ) ;
177
+ } else if let Some ( stmt) = block. stmts . iter ( ) . last ( ) {
178
+ match stmt. kind {
179
+ StmtKind :: Expr ( expr) | StmtKind :: Semi ( expr) => {
180
+ check_final_expr ( cx, expr, stmt. span , RetReplacement :: Empty ) ;
181
+ } ,
182
+ _ => ( ) ,
183
+ }
184
184
}
185
185
}
186
186
}
187
187
188
- fn check_final_expr < ' tcx > (
189
- cx : & LateContext < ' tcx > ,
190
- expr : & ' tcx Expr < ' tcx > ,
191
- span : Option < Span > ,
192
- replacement : RetReplacement ,
193
- ) {
194
- match expr. kind {
188
+ fn check_final_expr < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > , span : Span , replacement : RetReplacement ) {
189
+ match & expr. peel_drop_temps ( ) . kind {
195
190
// simple return is always "bad"
196
191
ExprKind :: Ret ( ref inner) => {
197
192
if cx. tcx . hir ( ) . attrs ( expr. hir_id ) . is_empty ( ) {
@@ -200,23 +195,17 @@ fn check_final_expr<'tcx>(
200
195
emit_return_lint (
201
196
cx,
202
197
inner. map_or ( expr. hir_id , |inner| inner. hir_id ) ,
203
- span. expect ( "`else return` is not possible" ) ,
198
+ span,
204
199
inner. as_ref ( ) . map ( |i| i. span ) ,
205
200
replacement,
206
201
) ;
207
202
}
208
203
}
209
204
} ,
210
- // a whole block? check it!
211
- ExprKind :: Block ( block, _) => {
212
- check_block_return ( cx, block) ;
213
- } ,
214
205
ExprKind :: If ( _, then, else_clause_opt) => {
215
- if let ExprKind :: Block ( ifblock, _) = then. kind {
216
- check_block_return ( cx, ifblock) ;
217
- }
206
+ check_block_return ( cx, & then. kind ) ;
218
207
if let Some ( else_clause) = else_clause_opt {
219
- check_final_expr ( cx, else_clause, None , RetReplacement :: Empty ) ;
208
+ check_block_return ( cx, & else_clause. kind )
220
209
}
221
210
} ,
222
211
// a match expr, check all arms
@@ -225,11 +214,11 @@ fn check_final_expr<'tcx>(
225
214
// (except for unit type functions) so we don't match it
226
215
ExprKind :: Match ( _, arms, MatchSource :: Normal ) => {
227
216
for arm in arms. iter ( ) {
228
- check_final_expr ( cx, arm. body , Some ( arm. body . span ) , RetReplacement :: Unit ) ;
217
+ check_final_expr ( cx, arm. body , arm. body . span , RetReplacement :: Unit ) ;
229
218
}
230
219
} ,
231
- ExprKind :: DropTemps ( expr ) => check_final_expr ( cx , expr , None , RetReplacement :: Empty ) ,
232
- _ => ( ) ,
220
+ // if it's a whole block, check it
221
+ other_expr_kind => check_block_return ( cx , & other_expr_kind ) ,
233
222
}
234
223
}
235
224
0 commit comments