@@ -44,6 +44,9 @@ pub enum BodyValidationDiagnostic {
4444 match_expr : ExprId ,
4545 uncovered_patterns : String ,
4646 } ,
47+ RemoveTrailingReturn {
48+ return_expr : ExprId ,
49+ } ,
4750 RemoveUnnecessaryElse {
4851 if_expr : ExprId ,
4952 } ,
@@ -75,6 +78,10 @@ impl ExprValidator {
7578 let body = db. body ( self . owner ) ;
7679 let mut filter_map_next_checker = None ;
7780
81+ if matches ! ( self . owner, DefWithBodyId :: FunctionId ( _) ) {
82+ self . check_for_trailing_return ( body. body_expr , & body) ;
83+ }
84+
7885 for ( id, expr) in body. exprs . iter ( ) {
7986 if let Some ( ( variant, missed_fields, true ) ) =
8087 record_literal_missing_fields ( db, & self . infer , id, expr)
@@ -93,12 +100,16 @@ impl ExprValidator {
93100 Expr :: Call { .. } | Expr :: MethodCall { .. } => {
94101 self . validate_call ( db, id, expr, & mut filter_map_next_checker) ;
95102 }
103+ Expr :: Closure { body : body_expr, .. } => {
104+ self . check_for_trailing_return ( * body_expr, & body) ;
105+ }
96106 Expr :: If { .. } => {
97107 self . check_for_unnecessary_else ( id, expr, & body) ;
98108 }
99109 _ => { }
100110 }
101111 }
112+
102113 for ( id, pat) in body. pats . iter ( ) {
103114 if let Some ( ( variant, missed_fields, true ) ) =
104115 record_pattern_missing_fields ( db, & self . infer , id, pat)
@@ -244,6 +255,38 @@ impl ExprValidator {
244255 pattern
245256 }
246257
258+ fn check_for_trailing_return ( & mut self , body_expr : ExprId , body : & Body ) {
259+ match & body. exprs [ body_expr] {
260+ Expr :: Block { statements, tail, .. } => {
261+ let last_stmt = tail. or_else ( || match statements. last ( ) ? {
262+ Statement :: Expr { expr, .. } => Some ( * expr) ,
263+ _ => None ,
264+ } ) ;
265+ if let Some ( last_stmt) = last_stmt {
266+ self . check_for_trailing_return ( last_stmt, body) ;
267+ }
268+ }
269+ Expr :: If { then_branch, else_branch, .. } => {
270+ self . check_for_trailing_return ( * then_branch, body) ;
271+ if let Some ( else_branch) = else_branch {
272+ self . check_for_trailing_return ( * else_branch, body) ;
273+ }
274+ }
275+ Expr :: Match { arms, .. } => {
276+ for arm in arms. iter ( ) {
277+ let MatchArm { expr, .. } = arm;
278+ self . check_for_trailing_return ( * expr, body) ;
279+ }
280+ }
281+ Expr :: Return { .. } => {
282+ self . diagnostics . push ( BodyValidationDiagnostic :: RemoveTrailingReturn {
283+ return_expr : body_expr,
284+ } ) ;
285+ }
286+ _ => ( ) ,
287+ }
288+ }
289+
247290 fn check_for_unnecessary_else ( & mut self , id : ExprId , expr : & Expr , body : & Body ) {
248291 if let Expr :: If { condition : _, then_branch, else_branch } = expr {
249292 if else_branch. is_none ( ) {
0 commit comments