Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0606db4

Browse files
committed
internal: Generally improve make::match_arm
`make::match_arm` should take a single `ast::Pat`, and callers can handle creating an `ast::OrPat` if need be. It should also take a proper `ast::MatchGuard`, instead of making one itself.
1 parent 6528650 commit 0606db4

File tree

9 files changed

+53
-56
lines changed

9 files changed

+53
-56
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
212212
!hidden
213213
})
214214
.map(|(pat, _)| {
215-
make::match_arm(iter::once(pat), None, make::ext::expr_todo())
216-
.clone_for_update()
215+
make::match_arm(pat, None, make::ext::expr_todo()).clone_for_update()
217216
});
218217

219218
let catch_all_arm = new_match_arm_list
@@ -243,12 +242,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
243242

244243
if needs_catch_all_arm && !has_catch_all_arm {
245244
cov_mark::hit!(added_wildcard_pattern);
246-
let arm = make::match_arm(
247-
iter::once(make::wildcard_pat().into()),
248-
None,
249-
make::ext::expr_todo(),
250-
)
251-
.clone_for_update();
245+
let arm =
246+
make::match_arm(make::wildcard_pat().into(), None, make::ext::expr_todo())
247+
.clone_for_update();
252248
todo_placeholders.push(arm.expr().unwrap());
253249
added_arms.push(arm);
254250
}

src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,12 +1554,12 @@ impl FlowHandler {
15541554
let value_pat = make::ext::simple_ident_pat(make::name(some_name));
15551555
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
15561556
let value = make::expr_path(make::ext::ident_path(some_name));
1557-
make::match_arm(iter::once(pat.into()), None, value)
1557+
make::match_arm(pat.into(), None, value)
15581558
};
15591559
let none_arm = {
15601560
let path = make::ext::ident_path("None");
15611561
let pat = make::path_pat(path);
1562-
make::match_arm(iter::once(pat), None, none.make_result_handler(None))
1562+
make::match_arm(pat, None, none.make_result_handler(None))
15631563
};
15641564
let arms = make::match_arm_list(vec![some_arm, none_arm]);
15651565
make::expr_match(call_expr, arms)
@@ -1573,18 +1573,14 @@ impl FlowHandler {
15731573
let value_pat = make::ext::simple_ident_pat(make::name(ok_name));
15741574
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
15751575
let value = make::expr_path(make::ext::ident_path(ok_name));
1576-
make::match_arm(iter::once(pat.into()), None, value)
1576+
make::match_arm(pat.into(), None, value)
15771577
};
15781578
let err_arm = {
15791579
let path = make::ext::ident_path("Err");
15801580
let value_pat = make::ext::simple_ident_pat(make::name(err_name));
15811581
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
15821582
let value = make::expr_path(make::ext::ident_path(err_name));
1583-
make::match_arm(
1584-
iter::once(pat.into()),
1585-
None,
1586-
err.make_result_handler(Some(value)),
1587-
)
1583+
make::match_arm(pat.into(), None, err.make_result_handler(Some(value)))
15881584
};
15891585
let arms = make::match_arm_list(vec![ok_arm, err_arm]);
15901586
make::expr_match(call_expr, arms)

src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,15 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
114114
let make_match_arm = |(pat, body): (_, ast::BlockExpr)| {
115115
let body = body.reset_indent().indent(IndentLevel(1));
116116
match pat {
117-
Either::Left(pat) => {
118-
make::match_arm(iter::once(pat), None, unwrap_trivial_block(body))
119-
}
117+
Either::Left(pat) => make::match_arm(pat, None, unwrap_trivial_block(body)),
120118
Either::Right(_) if !pat_seen => make::match_arm(
121-
iter::once(make::literal_pat("true").into()),
119+
make::literal_pat("true").into(),
122120
None,
123121
unwrap_trivial_block(body),
124122
),
125123
Either::Right(expr) => make::match_arm(
126-
iter::once(make::wildcard_pat().into()),
127-
Some(expr),
124+
make::wildcard_pat().into(),
125+
Some(make::match_guard(expr)),
128126
unwrap_trivial_block(body),
129127
),
130128
}
@@ -181,7 +179,7 @@ fn make_else_arm(
181179
};
182180
(pattern, make::ext::expr_unit())
183181
};
184-
make::match_arm(iter::once(pattern), None, expr)
182+
make::match_arm(pattern, None, expr)
185183
}
186184

187185
// Assist: replace_match_with_if_let

src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,11 @@ pub(crate) fn replace_try_expr_with_match(
7171
};
7272

7373
let happy_arm = make::match_arm(
74-
iter::once(
75-
try_enum.happy_pattern(make::ident_pat(false, false, make::name("it")).into()),
76-
),
74+
try_enum.happy_pattern(make::ident_pat(false, false, make::name("it")).into()),
7775
None,
7876
make::expr_path(make::ext::ident_path("it")),
7977
);
80-
let sad_arm = make::match_arm(iter::once(sad_pat), None, sad_expr);
78+
let sad_arm = make::match_arm(sad_pat, None, sad_expr);
8179

8280
let match_arm_list = make::match_arm_list([happy_arm, sad_arm]);
8381

src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,9 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
5454
let pats_after = pipe_token
5555
.siblings_with_tokens(Direction::Next)
5656
.filter_map(|it| ast::Pat::cast(it.into_node()?));
57-
// FIXME: We should add a leading pipe if the original arm has one.
58-
let new_match_arm = make::match_arm(
59-
pats_after,
60-
match_arm.guard().and_then(|guard| guard.condition()),
61-
match_arm_body,
62-
)
63-
.clone_for_update();
57+
let new_pat = make::or_pat(pats_after, or_pat.leading_pipe().is_some());
58+
let new_match_arm =
59+
make::match_arm(new_pat, match_arm.guard(), match_arm_body).clone_for_update();
6460

6561
let mut pipe_index = pipe_token.index();
6662
if pipe_token

src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
6666
let pat = make::record_pat(variant_name.clone(), pats.into_iter());
6767
let fields = make::record_expr_field_list(fields);
6868
let record_expr = make::record_expr(variant_name, fields).into();
69-
arms.push(make::match_arm(Some(pat.into()), None, record_expr));
69+
arms.push(make::match_arm(pat.into(), None, record_expr));
7070
}
7171

7272
// => match self { Self::Name(arg1) => Self::Name(arg1.clone()) }
@@ -84,14 +84,14 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
8484
let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
8585
let struct_name = make::expr_path(variant_name);
8686
let tuple_expr = make::expr_call(struct_name, make::arg_list(fields));
87-
arms.push(make::match_arm(Some(pat.into()), None, tuple_expr));
87+
arms.push(make::match_arm(pat.into(), None, tuple_expr));
8888
}
8989

9090
// => match self { Self::Name => Self::Name }
9191
None => {
9292
let pattern = make::path_pat(variant_name.clone());
9393
let variant_expr = make::expr_path(variant_name);
94-
arms.push(make::match_arm(Some(pattern), None, variant_expr));
94+
arms.push(make::match_arm(pattern, None, variant_expr));
9595
}
9696
}
9797
}
@@ -190,7 +190,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
190190

191191
// => MyStruct { fields.. } => f.debug_struct("MyStruct")...finish(),
192192
let pat = make::record_pat(variant_name.clone(), pats.into_iter());
193-
arms.push(make::match_arm(Some(pat.into()), None, expr));
193+
arms.push(make::match_arm(pat.into(), None, expr));
194194
}
195195
Some(ast::FieldList::TupleFieldList(list)) => {
196196
// => f.debug_tuple(name)
@@ -223,7 +223,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
223223

224224
// => MyStruct (fields..) => f.debug_tuple("MyStruct")...finish(),
225225
let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
226-
arms.push(make::match_arm(Some(pat.into()), None, expr));
226+
arms.push(make::match_arm(pat.into(), None, expr));
227227
}
228228
None => {
229229
let fmt_string = make::expr_literal(&(format!("\"{name}\""))).into();
@@ -232,7 +232,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
232232
let macro_call = make::expr_macro_call(macro_name, args);
233233

234234
let variant_name = make::path_pat(variant_name);
235-
arms.push(make::match_arm(Some(variant_name), None, macro_call));
235+
arms.push(make::match_arm(variant_name, None, macro_call));
236236
}
237237
}
238238
}
@@ -485,7 +485,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>) -
485485
let tuple = make::tuple_pat(vec![left.into(), right.into()]);
486486

487487
if let Some(expr) = expr {
488-
arms.push(make::match_arm(Some(tuple.into()), None, expr));
488+
arms.push(make::match_arm(tuple.into(), None, expr));
489489
}
490490
}
491491

@@ -518,7 +518,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>) -
518518
let tuple = make::tuple_pat(vec![left.into(), right.into()]);
519519

520520
if let Some(expr) = expr {
521-
arms.push(make::match_arm(Some(tuple.into()), None, expr));
521+
arms.push(make::match_arm(tuple.into(), None, expr));
522522
}
523523
}
524524
None => continue,
@@ -538,7 +538,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>) -
538538
} else {
539539
eq_check
540540
};
541-
arms.push(make::match_arm(Some(lhs), None, rhs));
541+
arms.push(make::match_arm(lhs, None, rhs));
542542
}
543543

544544
let match_target = make::expr_tuple([lhs_name, rhs_name]).into();
@@ -599,10 +599,10 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>)
599599
let variant_name =
600600
make::path_pat(make::ext::path_from_idents(["core", "cmp", "Ordering", "Equal"])?);
601601
let lhs = make::tuple_struct_pat(make::ext::path_from_idents(["Some"])?, [variant_name]);
602-
arms.push(make::match_arm(Some(lhs.into()), None, make::expr_empty_block()));
602+
arms.push(make::match_arm(lhs.into(), None, make::expr_empty_block()));
603603

604604
arms.push(make::match_arm(
605-
[make::ident_pat(false, false, make::name("ord")).into()],
605+
make::ident_pat(false, false, make::name("ord")).into(),
606606
None,
607607
make::expr_return(Some(make::expr_path(make::ext::ident_path("ord")))),
608608
));

src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ impl<N: AstNode + Clone> AstNodeEdit for N {}
153153
#[test]
154154
fn test_increase_indent() {
155155
let arm_list = {
156-
let arm =
157-
make::match_arm(iter::once(make::wildcard_pat().into()), None, make::ext::expr_unit());
156+
let arm = make::match_arm(make::wildcard_pat().into(), None, make::ext::expr_unit());
158157
make::match_arm_list([arm.clone(), arm])
159158
};
160159
assert_eq!(

src/tools/rust-analyzer/crates/syntax/src/ast/make.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -787,15 +787,21 @@ pub fn path_pat(path: ast::Path) -> ast::Pat {
787787
}
788788
}
789789

790-
pub fn match_arm(
791-
pats: impl IntoIterator<Item = ast::Pat>,
792-
guard: Option<ast::Expr>,
793-
expr: ast::Expr,
794-
) -> ast::MatchArm {
795-
let pats_str = pats.into_iter().join(" | ");
790+
/// Returns a `Pat` if the path has just one segment, an `OrPat` otherwise.
791+
pub fn or_pat(pats: impl IntoIterator<Item = ast::Pat>, leading_pipe: bool) -> ast::Pat {
792+
let leading_pipe = if leading_pipe { "| " } else { "" };
793+
let pats = pats.into_iter().join(" | ");
794+
795+
return from_text(&format!("{leading_pipe}{pats}"));
796+
fn from_text(text: &str) -> ast::Pat {
797+
ast_from_text(&format!("fn f({text}: ())"))
798+
}
799+
}
800+
801+
pub fn match_arm(pat: ast::Pat, guard: Option<ast::MatchGuard>, expr: ast::Expr) -> ast::MatchArm {
796802
return match guard {
797-
Some(guard) => from_text(&format!("{pats_str} if {guard} => {expr}")),
798-
None => from_text(&format!("{pats_str} => {expr}")),
803+
Some(guard) => from_text(&format!("{pat} {guard} => {expr}")),
804+
None => from_text(&format!("{pat} => {expr}")),
799805
};
800806

801807
fn from_text(text: &str) -> ast::MatchArm {
@@ -816,6 +822,14 @@ pub fn match_arm_with_guard(
816822
}
817823
}
818824

825+
pub fn match_guard(condition: ast::Expr) -> ast::MatchGuard {
826+
return from_text(&format!("if {condition}"));
827+
828+
fn from_text(text: &str) -> ast::MatchGuard {
829+
ast_from_text(&format!("fn f() {{ match () {{() {text} => () }}"))
830+
}
831+
}
832+
819833
pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList {
820834
let arms_str = arms.into_iter().fold(String::new(), |mut acc, arm| {
821835
let needs_comma = arm.expr().is_none_or(|it| !it.is_block_like());

src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ mod tests {
335335
#[test]
336336
fn basic_usage() {
337337
let root = make::match_arm(
338-
[make::wildcard_pat().into()],
338+
make::wildcard_pat().into(),
339339
None,
340340
make::expr_tuple([
341341
make::expr_bin_op(

0 commit comments

Comments
 (0)