Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20759 from A4-Tacks/strongly-typed-conv-to-guarded
Fix untyped syntax tree ans casts for convert_to_guarded_return
Chayim Refael Friedman 6 months ago
parent 09bee25 · parent ad37af4 · commit daf1cd9
-rw-r--r--crates/ide-assists/src/handlers/convert_to_guarded_return.rs26
1 files changed, 14 insertions, 12 deletions
diff --git a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
index ae13f83fbc..2a0ed4dc9e 100644
--- a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
+++ b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -75,8 +75,8 @@ fn if_expr_to_guarded_return(
let let_chains = flat_let_chain(cond);
- let then_block = if_expr.then_branch()?;
- let then_block = then_block.stmt_list()?;
+ let then_branch = if_expr.then_branch()?;
+ let then_block = then_branch.stmt_list()?;
let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?;
@@ -84,17 +84,8 @@ fn if_expr_to_guarded_return(
return None;
}
- // FIXME: This relies on untyped syntax tree and casts to much. It should be
- // rewritten to use strongly-typed APIs.
-
// check for early return and continue
- let first_in_then_block = then_block.syntax().first_child()?;
- if ast::ReturnExpr::can_cast(first_in_then_block.kind())
- || ast::ContinueExpr::can_cast(first_in_then_block.kind())
- || first_in_then_block
- .children()
- .any(|x| ast::ReturnExpr::can_cast(x.kind()) || ast::ContinueExpr::can_cast(x.kind()))
- {
+ if is_early_block(&then_block) || is_never_block(&ctx.sema, &then_branch) {
return None;
}
@@ -284,6 +275,17 @@ fn clean_stmt_block(block: &ast::BlockExpr) -> ast::BlockExpr {
}
}
+fn is_early_block(then_block: &ast::StmtList) -> bool {
+ let is_early_expr =
+ |expr| matches!(expr, ast::Expr::ReturnExpr(_) | ast::Expr::ContinueExpr(_));
+ let into_expr = |stmt| match stmt {
+ ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr(),
+ _ => None,
+ };
+ then_block.tail_expr().is_some_and(is_early_expr)
+ || then_block.statements().filter_map(into_expr).any(is_early_expr)
+}
+
#[cfg(test)]
mod tests {
use crate::tests::{check_assist, check_assist_not_applicable};