@@ -78,7 +78,6 @@ impl RetReplacement {
7878 Self :: Empty => "remove `return`" ,
7979 Self :: Block => "replace `return` with an empty block" ,
8080 Self :: Unit => "replace `return` with a unit value" ,
81-
8281 }
8382 }
8483}
@@ -161,37 +160,33 @@ impl<'tcx> LateLintPass<'tcx> for Return {
161160 } else {
162161 RetReplacement :: Empty
163162 } ;
164- check_final_expr ( cx, body. value , Some ( body. value . span ) , replacement) ;
163+ check_final_expr ( cx, body. value , body. value . span , replacement) ;
165164 } ,
166165 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 ) ;
170167 } ,
171168 }
172169 }
173170}
174171
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+ }
184184 }
185185 }
186186}
187187
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 {
195190 // simple return is always "bad"
196191 ExprKind :: Ret ( ref inner) => {
197192 if cx. tcx . hir ( ) . attrs ( expr. hir_id ) . is_empty ( ) {
@@ -200,23 +195,17 @@ fn check_final_expr<'tcx>(
200195 emit_return_lint (
201196 cx,
202197 inner. map_or ( expr. hir_id , |inner| inner. hir_id ) ,
203- span. expect ( "`else return` is not possible" ) ,
198+ span,
204199 inner. as_ref ( ) . map ( |i| i. span ) ,
205200 replacement,
206201 ) ;
207202 }
208203 }
209204 } ,
210- // a whole block? check it!
211- ExprKind :: Block ( block, _) => {
212- check_block_return ( cx, block) ;
213- } ,
214205 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 ) ;
218207 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 )
220209 }
221210 } ,
222211 // a match expr, check all arms
@@ -225,11 +214,11 @@ fn check_final_expr<'tcx>(
225214 // (except for unit type functions) so we don't match it
226215 ExprKind :: Match ( _, arms, MatchSource :: Normal ) => {
227216 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 ) ;
229218 }
230219 } ,
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 ) ,
233222 }
234223}
235224
0 commit comments