diff options
Diffstat (limited to 'crates/ra_assists/src/handlers')
-rw-r--r-- | crates/ra_assists/src/handlers/fill_match_arms.rs | 44 |
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}; | |||
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
6 | use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; | 6 | use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; |
7 | use test_utils::tested_by; | ||
7 | 8 | ||
8 | use crate::{AssistContext, AssistId, Assists}; | 9 | use 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)] |
169 | mod tests { | 176 | mod 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#" | ||
755 | fn 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#" | ||
766 | fn foo(opt: Option<i32>) { | ||
767 | match <|>opt { | ||
768 | Some(_) => {} | ||
769 | None => {} | ||
770 | } | ||
771 | } | ||
772 | "#, | ||
773 | ); | ||
774 | } | ||
739 | } | 775 | } |