Merge pull request #21412 from A4-Tacks/move-guard-exist
Fix loses exists guard for move_guard
This commit is contained in:
commit
38fb3a7dbb
1 changed files with 60 additions and 5 deletions
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue