Skip to content

Commit d8c0833

Browse files
authored
Merge branch 'rust-lang:master' into master
2 parents d9e17db + 3493b4c commit d8c0833

File tree

1 file changed

+38
-36
lines changed

1 file changed

+38
-36
lines changed

crates/ide-assists/src/handlers/move_guard.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
use itertools::Itertools;
12
use syntax::{
23
SyntaxKind::WHITESPACE,
3-
ast::{AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make},
4+
ast::{
5+
AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make,
6+
syntax_factory::SyntaxFactory,
7+
},
8+
syntax_editor::Element,
49
};
510

611
use crate::{AssistContext, AssistId, Assists};
@@ -131,8 +136,10 @@ pub(crate) fn move_arm_cond_to_match_guard(
131136
AssistId::refactor_rewrite("move_arm_cond_to_match_guard"),
132137
"Move condition to match guard",
133138
replace_node.text_range(),
134-
|edit| {
135-
edit.delete(match_arm.syntax().text_range());
139+
|builder| {
140+
let make = SyntaxFactory::without_mappings();
141+
let mut replace_arms = vec![];
142+
136143
// Dedent if if_expr is in a BlockExpr
137144
let dedent = if needs_dedent {
138145
cov_mark::hit!(move_guard_ifelse_in_block);
@@ -141,47 +148,30 @@ pub(crate) fn move_arm_cond_to_match_guard(
141148
cov_mark::hit!(move_guard_ifelse_else_block);
142149
0
143150
};
144-
let then_arm_end = match_arm.syntax().text_range().end();
145151
let indent_level = match_arm.indent_level();
146-
let spaces = indent_level;
147152

148-
let mut first = true;
149153
for (cond, block) in conds_blocks {
150-
if !first {
151-
edit.insert(then_arm_end, format!("\n{spaces}"));
152-
} else {
153-
first = false;
154-
}
155-
let guard = format!("{match_pat} if {cond} => ");
156-
edit.insert(then_arm_end, guard);
157154
let only_expr = block.statements().next().is_none();
158-
match &block.tail_expr() {
159-
Some(then_expr) if only_expr => {
160-
edit.insert(then_arm_end, then_expr.syntax().text());
161-
edit.insert(then_arm_end, ",");
162-
}
163-
_ => {
164-
let to_insert = block.dedent(dedent.into()).syntax().text();
165-
edit.insert(then_arm_end, to_insert)
166-
}
167-
}
155+
let expr = match block.tail_expr() {
156+
Some(then_expr) if only_expr => then_expr,
157+
_ => block.dedent(dedent.into()).into(),
158+
};
159+
let guard = make.match_guard(cond);
160+
let new_arm = make.match_arm(match_pat.clone(), Some(guard), expr);
161+
replace_arms.push(new_arm);
168162
}
169-
if let Some(e) = tail {
163+
if let Some(block) = tail {
170164
cov_mark::hit!(move_guard_ifelse_else_tail);
171-
let guard = format!("\n{spaces}{match_pat} => ");
172-
edit.insert(then_arm_end, guard);
173-
let only_expr = e.statements().next().is_none();
174-
match &e.tail_expr() {
165+
let only_expr = block.statements().next().is_none();
166+
let expr = match block.tail_expr() {
175167
Some(expr) if only_expr => {
176168
cov_mark::hit!(move_guard_ifelse_expr_only);
177-
edit.insert(then_arm_end, expr.syntax().text());
178-
edit.insert(then_arm_end, ",");
179-
}
180-
_ => {
181-
let to_insert = e.dedent(dedent.into()).syntax().text();
182-
edit.insert(then_arm_end, to_insert)
169+
expr
183170
}
184-
}
171+
_ => block.dedent(dedent.into()).into(),
172+
};
173+
let new_arm = make.match_arm(match_pat, None, expr);
174+
replace_arms.push(new_arm);
185175
} else {
186176
// There's no else branch. Add a pattern without guard, unless the following match
187177
// arm is `_ => ...`
@@ -193,9 +183,21 @@ pub(crate) fn move_arm_cond_to_match_guard(
193183
{
194184
cov_mark::hit!(move_guard_ifelse_has_wildcard);
195185
}
196-
_ => edit.insert(then_arm_end, format!("\n{spaces}{match_pat} => {{}}")),
186+
_ => {
187+
let block_expr = make.expr_empty_block().into();
188+
replace_arms.push(make.match_arm(match_pat, None, block_expr));
189+
}
197190
}
198191
}
192+
193+
let mut edit = builder.make_editor(match_arm.syntax());
194+
195+
let newline = make.whitespace(&format!("\n{indent_level}"));
196+
let replace_arms = replace_arms.iter().map(|it| it.syntax().syntax_element());
197+
let replace_arms = Itertools::intersperse(replace_arms, newline.syntax_element());
198+
edit.replace_with_many(match_arm.syntax(), replace_arms.collect());
199+
200+
builder.add_file_edits(ctx.vfs_file_id(), edit);
199201
},
200202
)
201203
}

0 commit comments

Comments
 (0)