@@ -44,6 +44,9 @@ pub enum BodyValidationDiagnostic {
44
44
match_expr : ExprId ,
45
45
uncovered_patterns : String ,
46
46
} ,
47
+ RemoveTrailingReturn {
48
+ return_expr : ExprId ,
49
+ } ,
47
50
RemoveUnnecessaryElse {
48
51
if_expr : ExprId ,
49
52
} ,
@@ -75,6 +78,10 @@ impl ExprValidator {
75
78
let body = db. body ( self . owner ) ;
76
79
let mut filter_map_next_checker = None ;
77
80
81
+ if matches ! ( self . owner, DefWithBodyId :: FunctionId ( _) ) {
82
+ self . check_for_trailing_return ( body. body_expr , & body) ;
83
+ }
84
+
78
85
for ( id, expr) in body. exprs . iter ( ) {
79
86
if let Some ( ( variant, missed_fields, true ) ) =
80
87
record_literal_missing_fields ( db, & self . infer , id, expr)
@@ -93,12 +100,16 @@ impl ExprValidator {
93
100
Expr :: Call { .. } | Expr :: MethodCall { .. } => {
94
101
self . validate_call ( db, id, expr, & mut filter_map_next_checker) ;
95
102
}
103
+ Expr :: Closure { body : body_expr, .. } => {
104
+ self . check_for_trailing_return ( * body_expr, & body) ;
105
+ }
96
106
Expr :: If { .. } => {
97
107
self . check_for_unnecessary_else ( id, expr, & body) ;
98
108
}
99
109
_ => { }
100
110
}
101
111
}
112
+
102
113
for ( id, pat) in body. pats . iter ( ) {
103
114
if let Some ( ( variant, missed_fields, true ) ) =
104
115
record_pattern_missing_fields ( db, & self . infer , id, pat)
@@ -244,6 +255,38 @@ impl ExprValidator {
244
255
pattern
245
256
}
246
257
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
+
247
290
fn check_for_unnecessary_else ( & mut self , id : ExprId , expr : & Expr , body : & Body ) {
248
291
if let Expr :: If { condition : _, then_branch, else_branch } = expr {
249
292
if else_branch. is_none ( ) {
0 commit comments