1- use  clippy_utils:: diagnostics:: { span_lint_and_sugg,  span_lint_hir_and_then} ; 
2- use  clippy_utils:: source:: SpanRangeExt ; 
3- use  clippy_utils:: sugg:: has_enclosing_paren; 
4- use  clippy_utils:: visitors:: for_each_expr; 
5- use  clippy_utils:: { 
6-     binary_expr_needs_parentheses,  fn_def_id,  is_from_proc_macro,  is_inside_let_else,  is_res_lang_ctor,  path_res, 
7-     path_to_local_id,  span_contains_cfg, 
8- } ; 
9- use  core:: ops:: ControlFlow ; 
1+ use  clippy_utils:: diagnostics:: span_lint_and_sugg; 
2+ use  clippy_utils:: { is_from_proc_macro,  is_inside_let_else,  is_res_lang_ctor,  path_res} ; 
103use  rustc_errors:: Applicability ; 
114use  rustc_hir:: LangItem :: ResultErr ; 
125use  rustc_hir:: intravisit:: FnKind ; 
13- use  rustc_hir:: { 
14-     Block ,  Body ,  Expr ,  ExprKind ,  FnDecl ,  HirId ,  ItemKind ,  MatchSource ,  Node ,  OwnerNode ,  PatKind ,  Stmt ,  StmtKind , 
15- } ; 
6+ use  rustc_hir:: { Block ,  Body ,  ExprKind ,  FnDecl ,  HirId ,  ItemKind ,  MatchSource ,  Node ,  OwnerNode ,  Stmt ,  StmtKind } ; 
167use  rustc_lint:: { LateContext ,  LateLintPass ,  LintContext } ; 
17- use  rustc_middle:: ty:: GenericArgKind ; 
188use  rustc_middle:: ty:: adjustment:: Adjust ; 
199use  rustc_session:: declare_lint_pass; 
2010use  rustc_span:: Span ; 
2111use  rustc_span:: def_id:: LocalDefId ; 
22- use  rustc_span:: edition:: Edition ; 
2312
13+ mod  let_and_return; 
2414mod  needless_return; 
2515
2616declare_clippy_lint !  { 
@@ -184,57 +174,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
184174    } 
185175
186176    fn  check_block ( & mut  self ,  cx :  & LateContext < ' tcx > ,  block :  & ' tcx  Block < ' _ > )  { 
187-         // we need both a let-binding stmt and an expr 
188-         if  let  Some ( retexpr)  = block. expr 
189-             && let  Some ( stmt)  = block. stmts . last ( ) 
190-             && let  StmtKind :: Let ( local)  = & stmt. kind 
191-             && local. ty . is_none ( ) 
192-             && cx. tcx . hir_attrs ( local. hir_id ) . is_empty ( ) 
193-             && let  Some ( initexpr)  = & local. init 
194-             && let  PatKind :: Binding ( _,  local_id,  _,  _)  = local. pat . kind 
195-             && path_to_local_id ( retexpr,  local_id) 
196-             && ( cx. sess ( ) . edition ( )  >= Edition :: Edition2024  || !last_statement_borrows ( cx,  initexpr) ) 
197-             && !initexpr. span . in_external_macro ( cx. sess ( ) . source_map ( ) ) 
198-             && !retexpr. span . in_external_macro ( cx. sess ( ) . source_map ( ) ) 
199-             && !local. span . from_expansion ( ) 
200-             && !span_contains_cfg ( cx,  stmt. span . between ( retexpr. span ) ) 
201-         { 
202-             span_lint_hir_and_then ( 
203-                 cx, 
204-                 LET_AND_RETURN , 
205-                 retexpr. hir_id , 
206-                 retexpr. span , 
207-                 "returning the result of a `let` binding from a block" , 
208-                 |err| { 
209-                     err. span_label ( local. span ,  "unnecessary `let` binding" ) ; 
210- 
211-                     if  let  Some ( src)  = initexpr. span . get_source_text ( cx)  { 
212-                         let  sugg = if  binary_expr_needs_parentheses ( initexpr)  { 
213-                             if  has_enclosing_paren ( & src)  { 
214-                                 src. to_owned ( ) 
215-                             }  else  { 
216-                                 format ! ( "({src})" ) 
217-                             } 
218-                         }  else  if  !cx. typeck_results ( ) . expr_adjustments ( retexpr) . is_empty ( )  { 
219-                             if  has_enclosing_paren ( & src)  { 
220-                                 format ! ( "{src} as _" ) 
221-                             }  else  { 
222-                                 format ! ( "({src}) as _" ) 
223-                             } 
224-                         }  else  { 
225-                             src. to_owned ( ) 
226-                         } ; 
227-                         err. multipart_suggestion ( 
228-                             "return the expression directly" , 
229-                             vec ! [ ( local. span,  String :: new( ) ) ,  ( retexpr. span,  sugg) ] , 
230-                             Applicability :: MachineApplicable , 
231-                         ) ; 
232-                     }  else  { 
233-                         err. span_help ( initexpr. span ,  "this expression can be directly returned" ) ; 
234-                     } 
235-                 } , 
236-             ) ; 
237-         } 
177+         let_and_return:: check_block ( cx,  block) 
238178    } 
239179
240180    fn  check_fn ( 
@@ -249,23 +189,3 @@ impl<'tcx> LateLintPass<'tcx> for Return {
249189        needless_return:: check_fn ( cx,  kind,  body,  sp) ; 
250190    } 
251191} 
252- 
253- fn  last_statement_borrows < ' tcx > ( cx :  & LateContext < ' tcx > ,  expr :  & ' tcx  Expr < ' tcx > )  -> bool  { 
254-     for_each_expr ( cx,  expr,  |e| { 
255-         if  let  Some ( def_id)  = fn_def_id ( cx,  e) 
256-             && cx
257-                 . tcx 
258-                 . fn_sig ( def_id) 
259-                 . instantiate_identity ( ) 
260-                 . skip_binder ( ) 
261-                 . output ( ) 
262-                 . walk ( ) 
263-                 . any ( |arg| matches ! ( arg. kind( ) ,  GenericArgKind :: Lifetime ( re)  if  !re. is_static( ) ) ) 
264-         { 
265-             ControlFlow :: Break ( ( ) ) 
266-         }  else  { 
267-             ControlFlow :: Continue ( ( ) ) 
268-         } 
269-     } ) 
270-     . is_some ( ) 
271- } 
0 commit comments