Merge pull request #21412 from A4-Tacks/move-guard-exist

Fix loses exists guard for move_guard
This commit is contained in:
Shoyu Vanilla (Flint) 2026-01-13 07:16:28 +00:00 committed by GitHub
commit 38fb3a7dbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3,7 +3,7 @@ use syntax::{
SyntaxKind::WHITESPACE,
ast::{
AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make,
syntax_factory::SyntaxFactory,
prec::ExprPrecedence, syntax_factory::SyntaxFactory,
},
syntax_editor::Element,
};
@ -109,6 +109,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?;
let match_pat = match_arm.pat()?;
let arm_body = match_arm.expr()?;
let arm_guard = match_arm.guard().and_then(|it| it.condition());
let mut replace_node = None;
let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone()).or_else(|| {
@ -149,6 +150,25 @@ pub(crate) fn move_arm_cond_to_match_guard(
0
};
let indent_level = match_arm.indent_level();
let make_guard = |cond: Option<Expr>| {
let condition = match (arm_guard.clone(), cond) {
(None, None) => return None,
(None, Some(it)) | (Some(it), None) => it,
(Some(lhs), Some(rhs)) => {
let op_expr = |expr: Expr| {
if expr.precedence().needs_parentheses_in(ExprPrecedence::LAnd) {
make.expr_paren(expr).into()
} else {
expr
}
};
let op = syntax::ast::BinaryOp::LogicOp(syntax::ast::LogicOp::And);
let expr_bin = make.expr_bin(op_expr(lhs), op, op_expr(rhs));
expr_bin.into()
}
};
Some(make.match_guard(condition))
};
for (cond, block) in conds_blocks {
let only_expr = block.statements().next().is_none();
@ -156,8 +176,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
Some(then_expr) if only_expr => then_expr,
_ => block.dedent(dedent.into()).into(),
};
let guard = make.match_guard(cond);
let new_arm = make.match_arm(match_pat.clone(), Some(guard), expr);
let new_arm = make.match_arm(match_pat.clone(), make_guard(Some(cond)), expr);
replace_arms.push(new_arm);
}
if let Some(block) = tail {
@ -170,7 +189,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
}
_ => block.dedent(dedent.into()).into(),
};
let new_arm = make.match_arm(match_pat, None, expr);
let new_arm = make.match_arm(match_pat, make_guard(None), expr);
replace_arms.push(new_arm);
} else {
// There's no else branch. Add a pattern without guard, unless the following match
@ -185,7 +204,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
}
_ => {
let block_expr = make.expr_empty_block().into();
replace_arms.push(make.match_arm(match_pat, None, block_expr));
replace_arms.push(make.match_arm(match_pat, make_guard(None), block_expr));
}
}
}
@ -1081,6 +1100,42 @@ fn main() {
x => {}
}
}
"#,
)
}
#[test]
fn move_arm_cond_to_match_guard_elseif_exist_guard() {
check_assist(
move_arm_cond_to_match_guard,
r#"
fn main() {
let cond = true;
match 92 {
3 => true,
x if cond => if x $0> 10 {
false
} else if x > 5 {
true
} else if x > 4 || x < -2 {
false
} else {
true
},
}
}
"#,
r#"
fn main() {
let cond = true;
match 92 {
3 => true,
x if cond && x > 10 => false,
x if cond && x > 5 => true,
x if cond && (x > 4 || x < -2) => false,
x if cond => true,
}
}
"#,
)
}