aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers')
-rw-r--r--crates/ra_assists/src/handlers/fill_match_arms.rs44
1 files changed, 40 insertions, 4 deletions
diff --git a/crates/ra_assists/src/handlers/fill_match_arms.rs b/crates/ra_assists/src/handlers/fill_match_arms.rs
index 13c1e7e80..b57ff75ae 100644
--- a/crates/ra_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ra_assists/src/handlers/fill_match_arms.rs
@@ -4,8 +4,9 @@ use hir::{Adt, HasSource, ModuleDef, Semantics};
4use itertools::Itertools; 4use itertools::Itertools;
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; 6use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
7use test_utils::tested_by;
7 8
8use crate::{AssistContext, AssistId, Assists}; 9use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
9 10
10// Assist: fill_match_arms 11// Assist: fill_match_arms
11// 12//
@@ -49,12 +50,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
49 let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) { 50 let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
50 let variants = enum_def.variants(ctx.db); 51 let variants = enum_def.variants(ctx.db);
51 52
52 variants 53 let mut variants = variants
53 .into_iter() 54 .into_iter()
54 .filter_map(|variant| build_pat(ctx.db, module, variant)) 55 .filter_map(|variant| build_pat(ctx.db, module, variant))
55 .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) 56 .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
56 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) 57 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
57 .collect() 58 .collect::<Vec<_>>();
59 if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
60 // Match `Some` variant first.
61 tested_by!(option_order);
62 variants.reverse()
63 }
64 variants
58 } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { 65 } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
59 // Partial fill not currently supported for tuple of enums. 66 // Partial fill not currently supported for tuple of enums.
60 if !arms.is_empty() { 67 if !arms.is_empty() {
@@ -167,9 +174,13 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
167 174
168#[cfg(test)] 175#[cfg(test)]
169mod tests { 176mod tests {
170 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 177 use crate::{
178 tests::{check_assist, check_assist_not_applicable, check_assist_target},
179 utils::FamousDefs,
180 };
171 181
172 use super::fill_match_arms; 182 use super::fill_match_arms;
183 use test_utils::covers;
173 184
174 #[test] 185 #[test]
175 fn all_match_arms_provided() { 186 fn all_match_arms_provided() {
@@ -736,4 +747,29 @@ mod tests {
736 "#, 747 "#,
737 ); 748 );
738 } 749 }
750
751 #[test]
752 fn option_order() {
753 covers!(option_order);
754 let before = r#"
755fn foo(opt: Option<i32>) {
756 match opt<|> {
757 }
758}"#;
759 let before =
760 &format!("//- main.rs crate:main deps:core\n{}{}", before, FamousDefs::FIXTURE);
761
762 check_assist(
763 fill_match_arms,
764 before,
765 r#"
766fn foo(opt: Option<i32>) {
767 match <|>opt {
768 Some(_) => {}
769 None => {}
770 }
771}
772"#,
773 );
774 }
739} 775}