From 9a7afe1f3aaf39a8c3413a86d47afc2ab81aab7c Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 30 Sep 2025 13:04:01 +0800 Subject: [PATCH] Fix let-expr in lhs for convert_to_guarded_return Example --- ```rust fn main() { if$0 let Ok(x) = Err(92) && let Ok(y) = Ok(37) && x < 30 && let Some(y) = Some(8) { foo(x, y); } } ``` **Before this PR**: ```rust fn main() { let Ok(x) = Err(92) else { return }; if !(let Ok(y) = Ok(37) && x < 30) { return; } let Some(y) = Some(8) else { return }; foo(x, y); } ``` **After this PR**: ```rust 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); } ``` --- .../src/handlers/convert_to_guarded_return.rs | 104 +++++++++++++++++- 1 file 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 82213ae3217e..6b5a37513cbe 100644 --- a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -254,20 +254,25 @@ fn early_expression( fn flat_let_chain(mut expr: ast::Expr) -> Vec { 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 } @@ -493,6 +498,93 @@ fn main() { let Some(y) = Some(8) else { return }; foo(x, y); } +"#, + ); + + 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); +} "#, ); }