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

Commit fdb8aa2

Browse files
committed
Auto merge of rust-lang#15235 - omertuc:matchsemi, r=lowr
Stop inserting semicolon when extracting match arm # Overview Extracting a match arm value that has type unit into a function, when a comma already follows the match arm value, results in an invalid (syntax error) semicolon added between the newly generated function's generated call and the comma. # Example Running this extraction ```rust fn main() { match () { _ => $0()$0, }; } ``` would lead to ```rust fn main() { match () { _ => fun_name();, }; } fn fun_name() { } ``` # Issue / Fix details This happens because when there is no comma, rust-analyzer would simply add the comma and wouldn't even try to evaluate whether it needs to add a semicolon. But when the comma is there, it proceeds to evaluate whether it needs to add a semicolon and it looks like the evaluation logic erroneously ignores the possibility that we're in a match arm. IIUC it never makes sense to add a semicolon when we're extracting from a match arm value, so I've adjusted the logic to always decide against adding a semicolon when we're in a match arm
2 parents d9c43b1 + 9200d27 commit fdb8aa2

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,14 +1360,15 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> St
13601360
}
13611361

13621362
format_to!(buf, "{expr}");
1363-
let insert_comma = fun
1364-
.body
1365-
.parent()
1366-
.and_then(ast::MatchArm::cast)
1367-
.map_or(false, |it| it.comma_token().is_none());
1363+
let parent_match_arm = fun.body.parent().and_then(ast::MatchArm::cast);
1364+
let insert_comma = parent_match_arm.as_ref().is_some_and(|it| it.comma_token().is_none());
1365+
13681366
if insert_comma {
13691367
buf.push(',');
1370-
} else if fun.ret_ty.is_unit() && (!fun.outliving_locals.is_empty() || !expr.is_block_like()) {
1368+
} else if parent_match_arm.is_none()
1369+
&& fun.ret_ty.is_unit()
1370+
&& (!fun.outliving_locals.is_empty() || !expr.is_block_like())
1371+
{
13711372
buf.push(';');
13721373
}
13731374
buf
@@ -4611,6 +4612,29 @@ fn $0fun_name() -> i32 {
46114612
}
46124613
"#,
46134614
);
4615+
4616+
// Makes sure no semicolon is added for unit-valued match arms
4617+
check_assist(
4618+
extract_function,
4619+
r#"
4620+
fn main() {
4621+
match () {
4622+
_ => $0()$0,
4623+
}
4624+
}
4625+
"#,
4626+
r#"
4627+
fn main() {
4628+
match () {
4629+
_ => fun_name(),
4630+
}
4631+
}
4632+
4633+
fn $0fun_name() {
4634+
()
4635+
}
4636+
"#,
4637+
)
46144638
}
46154639

46164640
#[test]

0 commit comments

Comments
 (0)