@@ -75,26 +75,17 @@ fn if_expr_to_guarded_return(
7575
7676 let let_chains = flat_let_chain ( cond) ;
7777
78- let then_block = if_expr. then_branch ( ) ?;
79- let then_block = then_block . stmt_list ( ) ?;
78+ let then_branch = if_expr. then_branch ( ) ?;
79+ let then_block = then_branch . stmt_list ( ) ?;
8080
8181 let parent_block = if_expr. syntax ( ) . parent ( ) ?. ancestors ( ) . find_map ( ast:: BlockExpr :: cast) ?;
8282
8383 if parent_block. tail_expr ( ) ? != if_expr. clone ( ) . into ( ) {
8484 return None ;
8585 }
8686
87- // FIXME: This relies on untyped syntax tree and casts to much. It should be
88- // rewritten to use strongly-typed APIs.
89-
9087 // check for early return and continue
91- let first_in_then_block = then_block. syntax ( ) . first_child ( ) ?;
92- if ast:: ReturnExpr :: can_cast ( first_in_then_block. kind ( ) )
93- || ast:: ContinueExpr :: can_cast ( first_in_then_block. kind ( ) )
94- || first_in_then_block
95- . children ( )
96- . any ( |x| ast:: ReturnExpr :: can_cast ( x. kind ( ) ) || ast:: ContinueExpr :: can_cast ( x. kind ( ) ) )
97- {
88+ if is_early_block ( & then_block) || is_never_block ( & ctx. sema , & then_branch) {
9889 return None ;
9990 }
10091
@@ -284,6 +275,17 @@ fn clean_stmt_block(block: &ast::BlockExpr) -> ast::BlockExpr {
284275 }
285276}
286277
278+ fn is_early_block ( then_block : & ast:: StmtList ) -> bool {
279+ let is_early_expr =
280+ |expr| matches ! ( expr, ast:: Expr :: ReturnExpr ( _) | ast:: Expr :: ContinueExpr ( _) ) ;
281+ let into_expr = |stmt| match stmt {
282+ ast:: Stmt :: ExprStmt ( expr_stmt) => expr_stmt. expr ( ) ,
283+ _ => None ,
284+ } ;
285+ then_block. tail_expr ( ) . is_some_and ( is_early_expr)
286+ || then_block. statements ( ) . filter_map ( into_expr) . any ( is_early_expr)
287+ }
288+
287289#[ cfg( test) ]
288290mod tests {
289291 use crate :: tests:: { check_assist, check_assist_not_applicable} ;
0 commit comments