This commit is contained in:
Lukas Wirth 2021-07-01 21:10:45 +02:00
parent 1b9b2d1f40
commit 3d2490ca97

View file

@ -10,7 +10,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, TextRange};
// Assist: merge_match_arms // Assist: merge_match_arms
// //
// Merges identical match arms. // Merges the current match arm with the following if their bodies are identical.
// //
// ``` // ```
// enum Action { Move { distance: u32 }, Stop } // enum Action { Move { distance: u32 }, Stop }
@ -44,14 +44,11 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option
// We check if the following match arms match this one. We could, but don't, // We check if the following match arms match this one. We could, but don't,
// compare to the previous match arm as well. // compare to the previous match arm as well.
let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next))
.take_while(|arm| { .take_while(|arm| match arm.expr() {
if arm.guard().is_some() { Some(expr) if arm.guard().is_none() => {
return false; expr.syntax().text() == current_expr.syntax().text()
}
match arm.expr() {
Some(expr) => expr.syntax().text() == current_expr.syntax().text(),
None => false,
} }
_ => false,
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -77,10 +74,12 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option
let arm = format!("{} => {}", pats, current_expr.syntax().text()); let arm = format!("{} => {}", pats, current_expr.syntax().text());
let start = arms_to_merge.first().unwrap().syntax().text_range().start(); if let [first, .., last] = &*arms_to_merge {
let end = arms_to_merge.last().unwrap().syntax().text_range().end(); let start = first.syntax().text_range().start();
let end = last.syntax().text_range().end();
edit.replace(TextRange::new(start, end), arm); edit.replace(TextRange::new(start, end), arm);
}
}, },
) )
} }
@ -100,30 +99,30 @@ mod tests {
check_assist( check_assist(
merge_match_arms, merge_match_arms,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { A, B, C } enum X { A, B, C }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A => { 1i32$0 } X::A => { 1i32$0 }
X::B => { 1i32 } X::B => { 1i32 }
X::C => { 2i32 } X::C => { 2i32 }
} }
} }
"#, "#,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { A, B, C } enum X { A, B, C }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A | X::B => { 1i32 } X::A | X::B => { 1i32 }
X::C => { 2i32 } X::C => { 2i32 }
} }
} }
"#, "#,
); );
} }
@ -132,30 +131,30 @@ mod tests {
check_assist( check_assist(
merge_match_arms, merge_match_arms,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { A, B, C, D, E } enum X { A, B, C, D, E }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A | X::B => {$0 1i32 }, X::A | X::B => {$0 1i32 },
X::C | X::D => { 1i32 }, X::C | X::D => { 1i32 },
X::E => { 2i32 }, X::E => { 2i32 },
} }
} }
"#, "#,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { A, B, C, D, E } enum X { A, B, C, D, E }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A | X::B | X::C | X::D => { 1i32 }, X::A | X::B | X::C | X::D => { 1i32 },
X::E => { 2i32 }, X::E => { 2i32 },
} }
} }
"#, "#,
); );
} }
@ -164,30 +163,30 @@ mod tests {
check_assist( check_assist(
merge_match_arms, merge_match_arms,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { A, B, C, D, E } enum X { A, B, C, D, E }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A => { 1i32 }, X::A => { 1i32 },
X::B => { 2i$032 }, X::B => { 2i$032 },
_ => { 2i32 } _ => { 2i32 }
} }
} }
"#, "#,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { A, B, C, D, E } enum X { A, B, C, D, E }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A => { 1i32 }, X::A => { 1i32 },
_ => { 2i32 } _ => { 2i32 }
} }
} }
"#, "#,
); );
} }
@ -196,29 +195,29 @@ mod tests {
check_assist( check_assist(
merge_match_arms, merge_match_arms,
r#" r#"
enum X { A, B, C, D, E } enum X { A, B, C, D, E }
fn main() { fn main() {
match X::A { match X::A {
X::A$0 => 92, X::A$0 => 92,
X::B => 92, X::B => 92,
X::C => 92, X::C => 92,
X::D => 62, X::D => 62,
_ => panic!(), _ => panic!(),
} }
} }
"#, "#,
r#" r#"
enum X { A, B, C, D, E } enum X { A, B, C, D, E }
fn main() { fn main() {
match X::A { match X::A {
X::A | X::B | X::C => 92, X::A | X::B | X::C => 92,
X::D => 62, X::D => 62,
_ => panic!(), _ => panic!(),
} }
} }
"#, "#,
) )
} }
@ -227,22 +226,22 @@ mod tests {
check_assist_not_applicable( check_assist_not_applicable(
merge_match_arms, merge_match_arms,
r#" r#"
#[derive(Debug)] #[derive(Debug)]
enum X { enum X {
A(i32), A(i32),
B, B,
C C
} }
fn main() { fn main() {
let x = X::A; let x = X::A;
let y = match x { let y = match x {
X::A(a) if a > 5 => { $01i32 }, X::A(a) if a > 5 => { $01i32 },
X::B => { 1i32 }, X::B => { 1i32 },
X::C => { 2i32 } X::C => { 2i32 }
} }
} }
"#, "#,
); );
} }
} }