Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20764 from A4-Tacks/fix-guarded-rhs-let-else
Fix let-expr in lhs for convert_to_guarded_return
Lukas Wirth 6 months ago
parent bb21f0b · parent 9a7afe1 · commit dcc9af4
-rw-r--r--crates/ide-assists/src/handlers/convert_to_guarded_return.rs104
1 files changed, 98 insertions, 6 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 2a0ed4dc9e..7f4fb4c694 100644
--- a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
+++ b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -246,20 +246,25 @@ fn early_expression(
fn flat_let_chain(mut expr: ast::Expr) -> Vec<ast::Expr> {
let mut chains = vec![];
+ let mut reduce_cond = |rhs| {
+ if !matches!(rhs, ast::Expr::LetExpr(_))
+ && let Some(last) = chains.pop_if(|last| !matches!(last, ast::Expr::LetExpr(_)))
+ {
+ chains.push(make::expr_bin_op(rhs, ast::BinaryOp::LogicOp(ast::LogicOp::And), last));
+ } else {
+ chains.push(rhs);
+ }
+ };
while let ast::Expr::BinExpr(bin_expr) = &expr
&& bin_expr.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And))
&& let (Some(lhs), Some(rhs)) = (bin_expr.lhs(), bin_expr.rhs())
{
- if let Some(last) = chains.pop_if(|last| !matches!(last, ast::Expr::LetExpr(_))) {
- chains.push(make::expr_bin_op(rhs, ast::BinaryOp::LogicOp(ast::LogicOp::And), last));
- } else {
- chains.push(rhs);
- }
+ reduce_cond(rhs);
expr = lhs;
}
- chains.push(expr);
+ reduce_cond(expr);
chains.reverse();
chains
}
@@ -556,6 +561,93 @@ fn main() {
}
"#,
);
+
+ check_assist(
+ convert_to_guarded_return,
+ r#"
+fn main() {
+ if$0 let Ok(x) = Err(92)
+ && let Ok(y) = Ok(37)
+ && x < 30
+ && let Some(y) = Some(8)
+ {
+ foo(x, y);
+ }
+}
+"#,
+ r#"
+fn main() {
+ let Ok(x) = Err(92) else { return };
+ let Ok(y) = Ok(37) else { return };
+ if x >= 30 {
+ return;
+ }
+ let Some(y) = Some(8) else { return };
+ foo(x, y);
+}
+"#,
+ );
+
+ check_assist(
+ convert_to_guarded_return,
+ r#"
+fn main() {
+ if$0 cond
+ && let Ok(x) = Err(92)
+ && let Ok(y) = Ok(37)
+ && x < 30
+ && let Some(y) = Some(8)
+ {
+ foo(x, y);
+ }
+}
+"#,
+ r#"
+fn main() {
+ if !cond {
+ return;
+ }
+ let Ok(x) = Err(92) else { return };
+ let Ok(y) = Ok(37) else { return };
+ if x >= 30 {
+ return;
+ }
+ let Some(y) = Some(8) else { return };
+ foo(x, y);
+}
+"#,
+ );
+
+ check_assist(
+ convert_to_guarded_return,
+ r#"
+fn main() {
+ if$0 cond
+ && foo()
+ && let Ok(x) = Err(92)
+ && let Ok(y) = Ok(37)
+ && x < 30
+ && let Some(y) = Some(8)
+ {
+ foo(x, y);
+ }
+}
+"#,
+ r#"
+fn main() {
+ if !(cond && foo()) {
+ return;
+ }
+ let Ok(x) = Err(92) else { return };
+ let Ok(y) = Ok(37) else { return };
+ if x >= 30 {
+ return;
+ }
+ let Some(y) = Some(8) else { return };
+ foo(x, y);
+}
+"#,
+ );
}
#[test]