From 215f8966658954a9603a41f3d7039e7b7108f034 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 7 Jan 2022 23:44:14 +0000 Subject: [PATCH 01/27] compiles, but doesn't work yet --- .../src/handlers/merge_match_arms.rs | 62 ++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 0ebc5d267c..d7a084b499 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -1,5 +1,7 @@ use std::iter::successors; +use hir::{TypeInfo, HirDisplay}; +use itertools::Itertools; use syntax::{ algo::neighbor, ast::{self, AstNode}, @@ -40,13 +42,33 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option } let current_expr = current_arm.expr()?; let current_text_range = current_arm.syntax().text_range(); + let current_arm_types = get_arm_types(&ctx, ¤t_arm); // We check if the following match arms match this one. We could, but don't, // compare to the previous match arm as well. let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) .take_while(|arm| match arm.expr() { - Some(expr) if arm.guard().is_none() => { - expr.syntax().text() == current_expr.syntax().text() + Some(expr) if arm.guard().is_none() && arm.pat().is_some() => { + let same_text = expr.syntax().text() == current_expr.syntax().text(); + if !same_text { + return false; + } + + let arm_types = get_arm_types(&ctx, &arm); + for i in 0..arm_types.len() { + let other_arm_type = &arm_types[i].as_ref(); + let current_arm_type = current_arm_types[i].as_ref(); + if other_arm_type.is_some() && current_arm_type.is_some() { + let other_arm_type = other_arm_type.unwrap().original.clone().as_adt(); + let current_arm_type = current_arm_type.unwrap().original.clone().as_adt(); + println!("Same types!"); + println!("{:?}", other_arm_type); + println!("{:?}", current_arm_type); + return other_arm_type == current_arm_type; + } + } + + true } _ => false, }) @@ -88,6 +110,20 @@ fn contains_placeholder(a: &ast::MatchArm) -> bool { matches!(a.pat(), Some(ast::Pat::WildcardPat(..))) } +fn get_arm_types(ctx: &AssistContext, arm: &ast::MatchArm) -> Vec> { + match arm.pat() { + Some(ast::Pat::TupleStructPat(tp)) => tp + .fields() + .into_iter() + .map(|field| { + let pat_type = ctx.sema.type_of_pat(&field); + pat_type + }) + .collect_vec(), + _ => Vec::new(), + } +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; @@ -244,4 +280,26 @@ fn main() { "#, ); } + + #[test] + fn merge_match_arms_different_type() { + check_assist_not_applicable( + merge_match_arms, + r#" +fn func() { + match Result::::Ok(0) { + Ok(x) => $0x.to_string(), + Err(x) => x.to_string() + }; } +"#, + ); + } +} + +// fn func() { +// match Result::::Ok(0) { +// Ok(x) => x.to_string(), +// Err(x) => x.to_string() +// }; +// } From c9fc91822f4bd110bdda7fb30d568871139f72d0 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 12:44:45 +0000 Subject: [PATCH 02/27] minicore --- crates/ide_assists/src/handlers/merge_match_arms.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index d7a084b499..4f4f5290fd 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -58,13 +58,16 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option for i in 0..arm_types.len() { let other_arm_type = &arm_types[i].as_ref(); let current_arm_type = current_arm_types[i].as_ref(); - if other_arm_type.is_some() && current_arm_type.is_some() { - let other_arm_type = other_arm_type.unwrap().original.clone().as_adt(); - let current_arm_type = current_arm_type.unwrap().original.clone().as_adt(); + if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type, current_arm_type) { + let other_arm_type = &other_arm_type.original; + let current_arm_type = ¤t_arm_type.original; + println!("Same types!"); println!("{:?}", other_arm_type); println!("{:?}", current_arm_type); return other_arm_type == current_arm_type; + + } } @@ -285,7 +288,7 @@ fn main() { fn merge_match_arms_different_type() { check_assist_not_applicable( merge_match_arms, - r#" + r#"//- minicore: result fn func() { match Result::::Ok(0) { Ok(x) => $0x.to_string(), From 6a1b4912bf2d65ac2176cddf6556eb7c68ba5b31 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:14:29 +0000 Subject: [PATCH 03/27] removed some unused stuff --- crates/ide_assists/src/handlers/merge_match_arms.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 4f4f5290fd..81089771e1 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -48,7 +48,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option // compare to the previous match arm as well. let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) .take_while(|arm| match arm.expr() { - Some(expr) if arm.guard().is_none() && arm.pat().is_some() => { + Some(expr) if arm.guard().is_none() => { let same_text = expr.syntax().text() == current_expr.syntax().text(); if !same_text { return false; @@ -59,15 +59,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option let other_arm_type = &arm_types[i].as_ref(); let current_arm_type = current_arm_types[i].as_ref(); if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type, current_arm_type) { - let other_arm_type = &other_arm_type.original; - let current_arm_type = ¤t_arm_type.original; - - println!("Same types!"); - println!("{:?}", other_arm_type); - println!("{:?}", current_arm_type); - return other_arm_type == current_arm_type; - - + return &other_arm_type.original == ¤t_arm_type.original; } } From 9252c76255bb6996f8d0100fbccb095633640ae6 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:19:37 +0000 Subject: [PATCH 04/27] using classify() --- .../ide_assists/src/handlers/merge_match_arms.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 81089771e1..a397247e0f 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -1,6 +1,5 @@ use std::iter::successors; - -use hir::{TypeInfo, HirDisplay}; +use hir::TypeInfo; use itertools::Itertools; use syntax::{ algo::neighbor, @@ -282,9 +281,9 @@ fn main() { merge_match_arms, r#"//- minicore: result fn func() { - match Result::::Ok(0) { - Ok(x) => $0x.to_string(), - Err(x) => x.to_string() + match Result::::Ok(0f64) { + Ok(x) => $0x.classify(), + Err(x) => x.classify() }; } "#, @@ -293,8 +292,8 @@ fn func() { } // fn func() { -// match Result::::Ok(0) { -// Ok(x) => x.to_string(), -// Err(x) => x.to_string() +// match Result::::Ok(0f64) { +// Ok(x) => x.classify(), +// Err(x) => x.classify() // }; // } From d8a3e51a5f4d6dcb8da269470061bfbb6b50e81f Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:24:36 +0000 Subject: [PATCH 05/27] added tests for multiple fields --- .../src/handlers/merge_match_arms.rs | 50 +++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index a397247e0f..5b0a66529e 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -1,6 +1,6 @@ -use std::iter::successors; use hir::TypeInfo; use itertools::Itertools; +use std::iter::successors; use syntax::{ algo::neighbor, ast::{self, AstNode}, @@ -57,7 +57,9 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option for i in 0..arm_types.len() { let other_arm_type = &arm_types[i].as_ref(); let current_arm_type = current_arm_types[i].as_ref(); - if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type, current_arm_type) { + if let (Some(other_arm_type), Some(current_arm_type)) = + (other_arm_type, current_arm_type) + { return &other_arm_type.original == ¤t_arm_type.original; } } @@ -289,11 +291,41 @@ fn func() { "#, ); } -} -// fn func() { -// match Result::::Ok(0f64) { -// Ok(x) => x.classify(), -// Err(x) => x.classify() -// }; -// } + #[test] + fn merge_match_arms_different_type_multiple_fields() { + check_assist_not_applicable( + merge_match_arms, + r#"//- minicore: result +fn func() { + match Result::<(f64, f64), (f32, f32)>::Ok((0f64, 0f64)) { + Ok(x) => $0x.1.classify(), + Err(x) => x.1.classify() + }; +} +"#, + ); + } + + #[test] + fn merge_match_arms_same_type_multiple_fields() { + check_assist( + merge_match_arms, + r#"//- minicore: result +fn func() { + match Result::<(f64, f64), (f64, f64)>::Ok((0f64, 0f64)) { + Ok(x) => $0x.1.classify(), + Err(x) => x.1.classify() + }; +} +"#, + r#" +fn func() { + match Result::<(f64, f64), (f64, f64)>::Ok((0f64, 0f64)) { + Ok(x) | Err(x) => x.1.classify(), + }; +} +"#, + ); + } +} From c52605024c2e6dfb3cc41728bd246b6073ec4998 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:30:27 +0000 Subject: [PATCH 06/27] extracted function --- .../src/handlers/merge_match_arms.rs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 5b0a66529e..75710b138f 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -1,4 +1,3 @@ -use hir::TypeInfo; use itertools::Itertools; use std::iter::successors; use syntax::{ @@ -53,18 +52,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option return false; } - let arm_types = get_arm_types(&ctx, &arm); - for i in 0..arm_types.len() { - let other_arm_type = &arm_types[i].as_ref(); - let current_arm_type = current_arm_types[i].as_ref(); - if let (Some(other_arm_type), Some(current_arm_type)) = - (other_arm_type, current_arm_type) - { - return &other_arm_type.original == ¤t_arm_type.original; - } - } - - true + return are_same_types(¤t_arm_types, arm, ctx); } _ => false, }) @@ -106,7 +94,24 @@ fn contains_placeholder(a: &ast::MatchArm) -> bool { matches!(a.pat(), Some(ast::Pat::WildcardPat(..))) } -fn get_arm_types(ctx: &AssistContext, arm: &ast::MatchArm) -> Vec> { +fn are_same_types( + current_arm_types: &Vec>, + arm: &ast::MatchArm, + ctx: &AssistContext, +) -> bool { + let arm_types = get_arm_types(&ctx, &arm); + for i in 0..arm_types.len() { + let other_arm_type = &arm_types[i].as_ref(); + let current_arm_type = current_arm_types[i].as_ref(); + if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type, current_arm_type) { + return &other_arm_type.original == ¤t_arm_type.original; + } + } + + return true; +} + +fn get_arm_types(ctx: &AssistContext, arm: &ast::MatchArm) -> Vec> { match arm.pat() { Some(ast::Pat::TupleStructPat(tp)) => tp .fields() From 5dfc8da77ec9641670cc82232d7bb979a7e9d33b Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:33:28 +0000 Subject: [PATCH 07/27] don't need the as_ref() --- crates/ide_assists/src/handlers/merge_match_arms.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 75710b138f..de796bcc38 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -101,8 +101,8 @@ fn are_same_types( ) -> bool { let arm_types = get_arm_types(&ctx, &arm); for i in 0..arm_types.len() { - let other_arm_type = &arm_types[i].as_ref(); - let current_arm_type = current_arm_types[i].as_ref(); + let other_arm_type = &arm_types[i]; + let current_arm_type = ¤t_arm_types[i]; if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type, current_arm_type) { return &other_arm_type.original == ¤t_arm_type.original; } From 130f11f27087fb722d3f5c578886e29fa2863272 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:38:17 +0000 Subject: [PATCH 08/27] simplified chain --- crates/ide_assists/src/handlers/merge_match_arms.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index de796bcc38..b61edc8964 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -113,14 +113,9 @@ fn are_same_types( fn get_arm_types(ctx: &AssistContext, arm: &ast::MatchArm) -> Vec> { match arm.pat() { - Some(ast::Pat::TupleStructPat(tp)) => tp - .fields() - .into_iter() - .map(|field| { - let pat_type = ctx.sema.type_of_pat(&field); - pat_type - }) - .collect_vec(), + Some(ast::Pat::TupleStructPat(tp)) => { + tp.fields().into_iter().map(|field| ctx.sema.type_of_pat(&field)).collect_vec() + } _ => Vec::new(), } } From 5675e0cd409ab4d3ca0c1717e7ec41825d4a3315 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:46:47 +0000 Subject: [PATCH 09/27] test cases with more branches --- .../src/handlers/merge_match_arms.rs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index b61edc8964..8983aada34 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -325,6 +325,64 @@ fn func() { Ok(x) | Err(x) => x.1.classify(), }; } +"#, + ); + } + + #[test] + fn merge_match_arms_same_type_subsequent_arm_with_different_type_in_other() { + check_assist( + merge_match_arms, + r#" +enum MyEnum { + OptionA(f32), + OptionB(f32), + OptionC(f64) +} + +fn func(e: MyEnum) { + match e { + MyEnum::OptionA(x) => $0x.classify(), + MyEnum::OptionB(x) => x.classify(), + MyEnum::OptionC(x) => x.classify(), + }; +} +"#, + r#" +enum MyEnum { + OptionA(f32), + OptionB(f32), + OptionC(f64) +} + +fn func(e: MyEnum) { + match e { + MyEnum::OptionA(x) | MyEnum::OptionB(x) => x.classify(), + MyEnum::OptionC(x) => x.classify(), + }; +} +"#, + ); + } + + #[test] + fn merge_match_arms_same_type_skip_arm_with_different_type_in_between() { + check_assist_not_applicable( + merge_match_arms, + r#" +enum MyEnum { + OptionA(f32), + OptionB(f64), + OptionC(f32) +} + +fn func(e: MyEnum) { + match e { + MyEnum::OptionA(x) => $0x.classify(), + MyEnum::OptionB(x) => x.classify(), + MyEnum::OptionC(x) => x.classify(), + }; +} "#, ); } From 2329b4240742acc46527c130e9ca61d632c9d6dc Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 18:54:59 +0000 Subject: [PATCH 10/27] test for different number of fields --- .../ide_assists/src/handlers/merge_match_arms.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 8983aada34..e7cd285d19 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -383,6 +383,21 @@ fn func(e: MyEnum) { MyEnum::OptionC(x) => x.classify(), }; } +"#, + ); + } + + #[test] + fn merge_match_arms_same_type_different_number_of_fields() { + check_assist_not_applicable( + merge_match_arms, + r#"//- minicore: result +fn func() { + match Result::<(f64, f64), (f64)>::Ok((0f64, 0f64)) { + Ok(x) => $0x.1.classify(), + Err(x) => x.1.classify() + }; +} "#, ); } From b27b882e7249d2058793898c4b9777c9468892af Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Mon, 10 Jan 2022 23:10:09 +0000 Subject: [PATCH 11/27] fixed test case --- crates/ide_assists/src/handlers/merge_match_arms.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index e7cd285d19..c6da1c17b5 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -393,7 +393,7 @@ fn func(e: MyEnum) { merge_match_arms, r#"//- minicore: result fn func() { - match Result::<(f64, f64), (f64)>::Ok((0f64, 0f64)) { + match Result::<(f64, f64, f64), (f64, f64)>::Ok((0f64, 0f64, 0f64)) { Ok(x) => $0x.1.classify(), Err(x) => x.1.classify() }; From 169ec2fdc1dfe18b56a3bd8e2f6162587b397e47 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 20:05:56 +0000 Subject: [PATCH 12/27] Added a few more test cases --- .../src/handlers/merge_match_arms.rs | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index c6da1c17b5..a5869104dd 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -401,4 +401,251 @@ fn func() { "#, ); } + + #[test] + fn merge_match_same_destructuring_different_types() { + check_assist_not_applicable( + merge_match_arms, + r#" +struct Point { + x: i32, + y: i32, +} + +fn func() { + let p = Point { x: 0, y: 7 }; + + match p { + Point { x, y: 0 } => $0"", + Point { x: 0, y } => "", + Point { x, y } => "", + }; +} +"#, + ); + } + + #[test] + fn merge_match_arms_range() { + check_assist( + merge_match_arms, + r#" +let x = 'c'; + + match x { + 'a'..='j' => $0"", + 'c'..='z' => "", + _ => "other", + }; +"#, + r#" +let x = 'c'; + + match x { + 'a'..='j' | 'c'..='z' => "", + _ => "other", + }; +"#, + ); + } + + #[test] + fn merge_match_arms_enum_without_field() { + check_assist_not_applicable( + merge_match_arms, + r#" +enum MyEnum { + NoField, + AField(u8) +} + +fn func(x: MyEnum) { + match x { + MyEnum::NoField => $0"", + MyEnum::AField(x) => "" + }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_enum_destructuring_different_types() { + check_assist_not_applicable( + merge_match_arms, + r#" +enum MyEnum { + Move { x: i32, y: i32 }, + Write(String), +} + +fn func(x: MyEnum) { + match x { + MyEnum::Move { x, y } => $0"", + MyEnum::Write(text) => "", + }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_enum_destructuring_same_types() { + check_assist( + merge_match_arms, + r#" +enum MyEnum { + Move { x: i32, y: i32 }, + Crawl { x: i32, y: i32 } +} + +fn func(x: MyEnum) { + match x { + MyEnum::Move { x, y } => $0"", + MyEnum::Crawl { x, y } => "", + }; +} + "#, + r#" +enum MyEnum { + Move { x: i32, y: i32 }, + Crawl { x: i32, y: i32 } +} + +fn func(x: MyEnum) { + match x { + MyEnum::Move { x, y } | MyEnum::Crawl { x, y } => "", + }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_enum_destructuring_same_types_different_name() { + check_assist_not_applicable( + merge_match_arms, + r#" +enum MyEnum { + Move { x: i32, y: i32 }, + Crawl { a: i32, b: i32 } +} + +fn func(x: MyEnum) { + match x { + MyEnum::Move { x, y } => $0"", + MyEnum::Crawl { a, b } => "", + }; +} + "# + ) + } + + #[test] + fn merge_match_arms_enum_nested_pattern_different_names() { + check_assist_not_applicable( + merge_match_arms, + r#" +enum Color { + Rgb(i32, i32, i32), + Hsv(i32, i32, i32), +} + +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(Color), +} + +fn main(msg: Message) { + match msg { + Message::ChangeColor(Color::Rgb(r, g, b)) => $0"", + Message::ChangeColor(Color::Hsv(h, s, v)) => "", + _ => "other" + }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_enum_nested_pattern_same_names() { + check_assist( + merge_match_arms, + r#" +enum Color { + Rgb(i32, i32, i32), + Hsv(i32, i32, i32), +} + +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(Color), +} + +fn main(msg: Message) { + match msg { + Message::ChangeColor(Color::Rgb(a, b, c)) => $0"", + Message::ChangeColor(Color::Hsv(a, b, c)) => "", + _ => "other" + }; +} + "#, + r#" +enum Color { + Rgb(i32, i32, i32), + Hsv(i32, i32, i32), +} + +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(Color), +} + +fn main(msg: Message) { + match msg { + Message::ChangeColor(Color::Rgb(a, b, c)) | Message::ChangeColor(Color::Hsv(a, b, c)) => "", + _ => "other" + }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_enum_destructuring_with_ignore() { + check_assist( + merge_match_arms, + r#" +enum MyEnum { + Move { x: i32, a: i32 }, + Crawl { x: i32, b: i32 } +} + +fn func(x: MyEnum) { + match x { + MyEnum::Move { x, .. } => $0"", + MyEnum::Crawl { x, .. } => "", + }; +} + "#, + r#" +enum MyEnum { + Move { x: i32, a: i32 }, + Crawl { x: i32, b: i32 } +} + +fn func(x: MyEnum) { + match x { + MyEnum::Move { x, .. } | MyEnum::Crawl { x, .. } => "", + }; +} + "#, + ) + } } From aaec467cfde482ce7959ea1452138f71202f8dfd Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 20:17:47 +0000 Subject: [PATCH 13/27] merge_match_arms_nested_with_conflicting_identifier --- .../src/handlers/merge_match_arms.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index a5869104dd..49543861c2 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -648,4 +648,32 @@ fn func(x: MyEnum) { "#, ) } + + #[test] + fn merge_match_arms_nested_with_conflicting_identifier() { + check_assist_not_applicable( + merge_match_arms, + r#" +enum Color { + Rgb(i32, i32, i32), + Hsv(i32, i32, i32), } + +enum Message { + Move { x: i32, y: i32 }, + ChangeColor(u8, Color), +} + +fn main(msg: Message) { + match msg { + Message::ChangeColor(x, Color::Rgb(y, b, c)) => $0"", + Message::ChangeColor(y, Color::Hsv(x, b, c)) => "", + _ => "other" + }; +} + "#, + ) + } +} + + From 18fb5412b2c9b05a767ed6c315c3521453cd50fc Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 21:39:50 +0000 Subject: [PATCH 14/27] all tests work --- .../src/handlers/merge_match_arms.rs | 76 ++++++++++++++----- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 49543861c2..7f9b5f4597 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -1,8 +1,8 @@ -use itertools::Itertools; -use std::iter::successors; +use hir::TypeInfo; +use std::{iter::successors, collections::HashMap}; use syntax::{ algo::neighbor, - ast::{self, AstNode}, + ast::{self, AstNode, Pat, MatchArm, HasName}, Direction, }; @@ -52,6 +52,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option return false; } + println!("Checking types"); return are_same_types(¤t_arm_types, arm, ctx); } _ => false, @@ -90,34 +91,69 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option ) } -fn contains_placeholder(a: &ast::MatchArm) -> bool { +fn contains_placeholder(a: &MatchArm) -> bool { matches!(a.pat(), Some(ast::Pat::WildcardPat(..))) } fn are_same_types( - current_arm_types: &Vec>, + current_arm_types: &HashMap>, arm: &ast::MatchArm, ctx: &AssistContext, ) -> bool { let arm_types = get_arm_types(&ctx, &arm); - for i in 0..arm_types.len() { - let other_arm_type = &arm_types[i]; - let current_arm_type = ¤t_arm_types[i]; - if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type, current_arm_type) { - return &other_arm_type.original == ¤t_arm_type.original; + for other_arm_type_entry in arm_types { + let current_arm_type = current_arm_types.get_key_value(&other_arm_type_entry.0); + if current_arm_type.is_none() { + println!("No corresponding type found for {:?}", {other_arm_type_entry}); + return false; + } + + let unwrapped_current_arm_type = current_arm_type.unwrap().1; + + if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type_entry.1, unwrapped_current_arm_type) { + if other_arm_type.original != current_arm_type.original { + println!("Type {:?} is different from {:?}", &other_arm_type.original, ¤t_arm_type.original); + return false; + } } } return true; } -fn get_arm_types(ctx: &AssistContext, arm: &ast::MatchArm) -> Vec> { - match arm.pat() { - Some(ast::Pat::TupleStructPat(tp)) => { - tp.fields().into_iter().map(|field| ctx.sema.type_of_pat(&field)).collect_vec() +fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap> { + let mut mapping: HashMap> = HashMap::new(); + + fn recurse(pat: &Option, map: &mut HashMap>, ctx: &AssistContext) { + if let Some(local_pat) = pat { + println!("{:?}", pat); + match pat { + Some(ast::Pat::TupleStructPat(tuple)) => { + for field in tuple.fields() { + recurse(&Some(field), map, ctx); + } + }, + Some(ast::Pat::RecordPat(record)) => { + if let Some(field_list) = record.record_pat_field_list() { + for field in field_list.fields() { + recurse(&field.pat(), map, ctx); + } + } + }, + Some(ast::Pat::IdentPat(ident_pat)) => { + if let Some(name) = ident_pat.name() { + println!("Found name: {:?}", name.text().to_string()); + let pat_type = ctx.sema.type_of_pat(local_pat); + map.insert(name.text().to_string(), pat_type); + } + }, + _ => (), + } } - _ => Vec::new(), } + + recurse(&arm.pat(), &mut mapping, &context); + return mapping; } #[cfg(test)] @@ -430,21 +466,25 @@ fn func() { check_assist( merge_match_arms, r#" -let x = 'c'; +fn func() { + let x = 'c'; match x { 'a'..='j' => $0"", 'c'..='z' => "", _ => "other", }; +} "#, r#" -let x = 'c'; +fn func() { + let x = 'c'; match x { 'a'..='j' | 'c'..='z' => "", _ => "other", }; +} "#, ); } @@ -675,5 +715,3 @@ fn main(msg: Message) { ) } } - - From bd77d8c3d1c80ca375c3e9e3046af5ac8a4f515a Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 21:40:22 +0000 Subject: [PATCH 15/27] removed prints --- crates/ide_assists/src/handlers/merge_match_arms.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 7f9b5f4597..4e09bb2a70 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -52,7 +52,6 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option return false; } - println!("Checking types"); return are_same_types(¤t_arm_types, arm, ctx); } _ => false, @@ -104,7 +103,6 @@ fn are_same_types( for other_arm_type_entry in arm_types { let current_arm_type = current_arm_types.get_key_value(&other_arm_type_entry.0); if current_arm_type.is_none() { - println!("No corresponding type found for {:?}", {other_arm_type_entry}); return false; } @@ -112,7 +110,6 @@ fn are_same_types( if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type_entry.1, unwrapped_current_arm_type) { if other_arm_type.original != current_arm_type.original { - println!("Type {:?} is different from {:?}", &other_arm_type.original, ¤t_arm_type.original); return false; } } @@ -126,7 +123,6 @@ fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap, map: &mut HashMap>, ctx: &AssistContext) { if let Some(local_pat) = pat { - println!("{:?}", pat); match pat { Some(ast::Pat::TupleStructPat(tuple)) => { for field in tuple.fields() { @@ -142,7 +138,6 @@ fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap { if let Some(name) = ident_pat.name() { - println!("Found name: {:?}", name.text().to_string()); let pat_type = ctx.sema.type_of_pat(local_pat); map.insert(name.text().to_string(), pat_type); } From 7bc89f25426d39220c3f533191fb0b5290fe1582 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 21:40:57 +0000 Subject: [PATCH 16/27] formatting --- .../src/handlers/merge_match_arms.rs | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 4e09bb2a70..69d1bc0adc 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -1,8 +1,8 @@ use hir::TypeInfo; -use std::{iter::successors, collections::HashMap}; +use std::{collections::HashMap, iter::successors}; use syntax::{ algo::neighbor, - ast::{self, AstNode, Pat, MatchArm, HasName}, + ast::{self, AstNode, HasName, MatchArm, Pat}, Direction, }; @@ -107,8 +107,10 @@ fn are_same_types( } let unwrapped_current_arm_type = current_arm_type.unwrap().1; - - if let (Some(other_arm_type), Some(current_arm_type)) = (other_arm_type_entry.1, unwrapped_current_arm_type) { + + if let (Some(other_arm_type), Some(current_arm_type)) = + (other_arm_type_entry.1, unwrapped_current_arm_type) + { if other_arm_type.original != current_arm_type.original { return false; } @@ -120,28 +122,32 @@ fn are_same_types( fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap> { let mut mapping: HashMap> = HashMap::new(); - - fn recurse(pat: &Option, map: &mut HashMap>, ctx: &AssistContext) { + + fn recurse( + pat: &Option, + map: &mut HashMap>, + ctx: &AssistContext, + ) { if let Some(local_pat) = pat { match pat { Some(ast::Pat::TupleStructPat(tuple)) => { for field in tuple.fields() { recurse(&Some(field), map, ctx); } - }, + } Some(ast::Pat::RecordPat(record)) => { if let Some(field_list) = record.record_pat_field_list() { for field in field_list.fields() { recurse(&field.pat(), map, ctx); } } - }, + } Some(ast::Pat::IdentPat(ident_pat)) => { if let Some(name) = ident_pat.name() { let pat_type = ctx.sema.type_of_pat(local_pat); map.insert(name.text().to_string(), pat_type); } - }, + } _ => (), } } @@ -552,7 +558,7 @@ fn func(x: MyEnum) { MyEnum::Move { x, y } | MyEnum::Crawl { x, y } => "", }; } - "#, + "#, ) } @@ -572,7 +578,7 @@ fn func(x: MyEnum) { MyEnum::Crawl { a, b } => "", }; } - "# + "#, ) } @@ -629,7 +635,7 @@ fn main(msg: Message) { }; } "#, - r#" + r#" enum Color { Rgb(i32, i32, i32), Hsv(i32, i32, i32), @@ -680,7 +686,7 @@ fn func(x: MyEnum) { MyEnum::Move { x, .. } | MyEnum::Crawl { x, .. } => "", }; } - "#, + "#, ) } @@ -706,7 +712,7 @@ fn main(msg: Message) { _ => "other" }; } - "#, + "#, ) } } From 08300284e7632476592a715d28653db83bdef686 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 21:44:30 +0000 Subject: [PATCH 17/27] removed unwrap --- .../src/handlers/merge_match_arms.rs | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 69d1bc0adc..f5366bee12 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -101,19 +101,18 @@ fn are_same_types( ) -> bool { let arm_types = get_arm_types(&ctx, &arm); for other_arm_type_entry in arm_types { - let current_arm_type = current_arm_types.get_key_value(&other_arm_type_entry.0); - if current_arm_type.is_none() { - return false; - } - - let unwrapped_current_arm_type = current_arm_type.unwrap().1; - - if let (Some(other_arm_type), Some(current_arm_type)) = - (other_arm_type_entry.1, unwrapped_current_arm_type) - { - if other_arm_type.original != current_arm_type.original { - return false; + let current_arm_type_kv = current_arm_types.get_key_value(&other_arm_type_entry.0); + if let Some(current_arm_type) = current_arm_type_kv { + if let (Some(other_arm_type), Some(current_arm_type)) = + (other_arm_type_entry.1, current_arm_type.1) + { + if other_arm_type.original != current_arm_type.original { + return false; + } } + } else { + // No corresponding field found + return false; } } From 7daca6fe9733b64a2610c337c191785e12103ed0 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 21:50:42 +0000 Subject: [PATCH 18/27] cleaning up Some --- crates/ide_assists/src/handlers/merge_match_arms.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index f5366bee12..54de1c6c2f 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -100,12 +100,9 @@ fn are_same_types( ctx: &AssistContext, ) -> bool { let arm_types = get_arm_types(&ctx, &arm); - for other_arm_type_entry in arm_types { - let current_arm_type_kv = current_arm_types.get_key_value(&other_arm_type_entry.0); - if let Some(current_arm_type) = current_arm_type_kv { - if let (Some(other_arm_type), Some(current_arm_type)) = - (other_arm_type_entry.1, current_arm_type.1) - { + for (other_arm_type_name, other_arm_type) in arm_types { + if let Some((_, Some(current_arm_type))) = current_arm_types.get_key_value(&other_arm_type_name) { + if let Some(other_arm_type) = other_arm_type { if other_arm_type.original != current_arm_type.original { return false; } From a347cb5f863fbaf62e2ebc4d7ae8842f2efe8dec Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Tue, 11 Jan 2022 21:53:39 +0000 Subject: [PATCH 19/27] battle of the Some --- crates/ide_assists/src/handlers/merge_match_arms.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 54de1c6c2f..0ef4678d11 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -101,11 +101,11 @@ fn are_same_types( ) -> bool { let arm_types = get_arm_types(&ctx, &arm); for (other_arm_type_name, other_arm_type) in arm_types { - if let Some((_, Some(current_arm_type))) = current_arm_types.get_key_value(&other_arm_type_name) { - if let Some(other_arm_type) = other_arm_type { - if other_arm_type.original != current_arm_type.original { - return false; - } + if let (Some(Some(current_arm_type)), Some(other_arm_type)) = + (current_arm_types.get(&other_arm_type_name), other_arm_type) + { + if other_arm_type.original != current_arm_type.original { + return false; } } else { // No corresponding field found From c955ea11b42dc7c0ac91fe1a12427171b86be4b7 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 00:35:21 +0000 Subject: [PATCH 20/27] support TuplePat --- .../src/handlers/merge_match_arms.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 0ef4678d11..ff1804fe95 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -131,6 +131,11 @@ fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap { + for field in tuple.fields() { + recurse(&Some(field), map, ctx); + } + } Some(ast::Pat::RecordPat(record)) => { if let Some(field_list) = record.record_pat_field_list() { for field in field_list.fields() { @@ -707,6 +712,21 @@ fn main(msg: Message) { Message::ChangeColor(y, Color::Hsv(x, b, c)) => "", _ => "other" }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_tuple() { + check_assist_not_applicable( + merge_match_arms, + r#" +fn func() { + match (0, "boo") { + (x, y) => $0"", + (y, x) => "", + }; } "#, ) From 82d3238da8f6c33dc1beb07f3ec945d218615ab8 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 00:39:44 +0000 Subject: [PATCH 21/27] ParenPat --- .../src/handlers/merge_match_arms.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index ff1804fe95..ecb7d4bf07 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -143,6 +143,9 @@ fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap { + recurse(&parentheses.pat(), map, ctx); + } Some(ast::Pat::IdentPat(ident_pat)) => { if let Some(name) = ident_pat.name() { let pat_type = ctx.sema.type_of_pat(local_pat); @@ -727,6 +730,23 @@ fn func() { (x, y) => $0"", (y, x) => "", }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_parentheses() { + check_assist_not_applicable( + merge_match_arms, + r#" +fn func(x: i32) { + let variable = 2; + match x { + 1 => $0"", + ((((variable)))) => "", + _ => "other" + }; } "#, ) From 8deadb18ae2654ebbb07dc9b0e030fe1caebfacf Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 01:18:03 +0000 Subject: [PATCH 22/27] refpat & slicepat --- .../src/handlers/merge_match_arms.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index ecb7d4bf07..209d352c78 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -146,6 +146,11 @@ fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap { recurse(&parentheses.pat(), map, ctx); } + Some(ast::Pat::SlicePat(slice)) => { + for slice_pat in slice.pats() { + recurse(&Some(slice_pat), map, ctx); + } + } Some(ast::Pat::IdentPat(ident_pat)) => { if let Some(name) = ident_pat.name() { let pat_type = ctx.sema.type_of_pat(local_pat); @@ -747,6 +752,41 @@ fn func(x: i32) { ((((variable)))) => "", _ => "other" }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_refpat() { + check_assist_not_applicable( + merge_match_arms, + r#" +fn func() { + let name = Some(String::from("")); + let n = String::from(""); + match name { + Some(ref n) => $0"", + Some(n) => "", + _ => "other", + }; +} + "#, + ) + } + + #[test] + fn merge_match_arms_slice() { + check_assist_not_applicable( + merge_match_arms, + r#" +fn func(binary: &[u8]) { + let space = b' '; + match binary { + [0x7f, b'E', b'L', b'F', ..] => $0"", + [space] => "", + _ => "other", + }; } "#, ) From 5e4370fe56153df73c51cb532f0f1bf4c261b094 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 01:20:40 +0000 Subject: [PATCH 23/27] happy slice --- .../src/handlers/merge_match_arms.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 209d352c78..5337b968c5 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -791,4 +791,39 @@ fn func(binary: &[u8]) { "#, ) } + + #[test] + fn merge_match_arms_slice_identical() { + check_assist( + merge_match_arms, + r#" +fn func(binary: &[u8]) { + let space = b' '; + match binary { + [space, 5u8] => $0"", + [space] => "", + _ => "other", + }; } + "#, + r#" +fn func(binary: &[u8]) { + let space = b' '; + match binary { + [space, 5u8] | [space] => "", + _ => "other", + }; +} + "#, + ) + } +} + +fn func(binary: &[u8]) { + let space = b' '; + match binary { + [space, 5u8] => "", + [space] => "", + _ => "other", + }; +} \ No newline at end of file From e5cdde95abd6a48d4c6f3a82efdce24b46c86c17 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 01:22:19 +0000 Subject: [PATCH 24/27] removed toy --- crates/ide_assists/src/handlers/merge_match_arms.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 5337b968c5..ea372b205d 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -818,12 +818,3 @@ fn func(binary: &[u8]) { ) } } - -fn func(binary: &[u8]) { - let space = b' '; - match binary { - [space, 5u8] => "", - [space] => "", - _ => "other", - }; -} \ No newline at end of file From 0700282b75edb217d9ef0009e1524f9b638ae855 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 01:22:48 +0000 Subject: [PATCH 25/27] formatting --- crates/ide_assists/src/handlers/merge_match_arms.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index ea372b205d..0168e3faef 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -806,7 +806,7 @@ fn func(binary: &[u8]) { }; } "#, - r#" + r#" fn func(binary: &[u8]) { let space = b' '; match binary { From 683de877ce49d0abd472777a94d3038eee1ee060 Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 01:26:17 +0000 Subject: [PATCH 26/27] simple return --- crates/ide_assists/src/handlers/merge_match_arms.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 0168e3faef..da81d420f9 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -52,7 +52,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option return false; } - return are_same_types(¤t_arm_types, arm, ctx); + are_same_types(¤t_arm_types, arm, ctx) } _ => false, }) From ffe4352d7c0727c5a657bd240275fffe7144ba8d Mon Sep 17 00:00:00 2001 From: Jeroen Vannevel Date: Fri, 14 Jan 2022 18:53:28 +0000 Subject: [PATCH 27/27] styling fixes --- .../src/handlers/merge_match_arms.rs | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index da81d420f9..622ead81f1 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -2,7 +2,7 @@ use hir::TypeInfo; use std::{collections::HashMap, iter::successors}; use syntax::{ algo::neighbor, - ast::{self, AstNode, HasName, MatchArm, Pat}, + ast::{self, AstNode, HasName}, Direction, }; @@ -90,7 +90,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option ) } -fn contains_placeholder(a: &MatchArm) -> bool { +fn contains_placeholder(a: &ast::MatchArm) -> bool { matches!(a.pat(), Some(ast::Pat::WildcardPat(..))) } @@ -101,54 +101,55 @@ fn are_same_types( ) -> bool { let arm_types = get_arm_types(&ctx, &arm); for (other_arm_type_name, other_arm_type) in arm_types { - if let (Some(Some(current_arm_type)), Some(other_arm_type)) = - (current_arm_types.get(&other_arm_type_name), other_arm_type) - { - if other_arm_type.original != current_arm_type.original { - return false; + match (current_arm_types.get(&other_arm_type_name), other_arm_type) { + (Some(Some(current_arm_type)), Some(other_arm_type)) + if other_arm_type.original == current_arm_type.original => + { + () } - } else { - // No corresponding field found - return false; + _ => return false, } } - return true; + true } -fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap> { +fn get_arm_types( + context: &AssistContext, + arm: &ast::MatchArm, +) -> HashMap> { let mut mapping: HashMap> = HashMap::new(); fn recurse( - pat: &Option, map: &mut HashMap>, ctx: &AssistContext, + pat: &Option, ) { if let Some(local_pat) = pat { match pat { Some(ast::Pat::TupleStructPat(tuple)) => { for field in tuple.fields() { - recurse(&Some(field), map, ctx); + recurse(map, ctx, &Some(field)); } } Some(ast::Pat::TuplePat(tuple)) => { for field in tuple.fields() { - recurse(&Some(field), map, ctx); + recurse(map, ctx, &Some(field)); } } Some(ast::Pat::RecordPat(record)) => { if let Some(field_list) = record.record_pat_field_list() { for field in field_list.fields() { - recurse(&field.pat(), map, ctx); + recurse(map, ctx, &field.pat()); } } } Some(ast::Pat::ParenPat(parentheses)) => { - recurse(&parentheses.pat(), map, ctx); + recurse(map, ctx, &parentheses.pat()); } Some(ast::Pat::SlicePat(slice)) => { for slice_pat in slice.pats() { - recurse(&Some(slice_pat), map, ctx); + recurse(map, ctx, &Some(slice_pat)); } } Some(ast::Pat::IdentPat(ident_pat)) => { @@ -162,8 +163,8 @@ fn get_arm_types(context: &AssistContext, arm: &MatchArm) -> HashMap::Ok(0f64) { Ok(x) => $0x.classify(), @@ -342,7 +344,8 @@ fn func() { fn merge_match_arms_different_type_multiple_fields() { check_assist_not_applicable( merge_match_arms, - r#"//- minicore: result + r#" +//- minicore: result fn func() { match Result::<(f64, f64), (f32, f32)>::Ok((0f64, 0f64)) { Ok(x) => $0x.1.classify(), @@ -357,7 +360,8 @@ fn func() { fn merge_match_arms_same_type_multiple_fields() { check_assist( merge_match_arms, - r#"//- minicore: result + r#" +//- minicore: result fn func() { match Result::<(f64, f64), (f64, f64)>::Ok((0f64, 0f64)) { Ok(x) => $0x.1.classify(), @@ -437,7 +441,8 @@ fn func(e: MyEnum) { fn merge_match_arms_same_type_different_number_of_fields() { check_assist_not_applicable( merge_match_arms, - r#"//- minicore: result + r#" +//- minicore: result fn func() { match Result::<(f64, f64, f64), (f64, f64)>::Ok((0f64, 0f64, 0f64)) { Ok(x) => $0x.1.classify(),