aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers/fill_match_arms.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers/fill_match_arms.rs')
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs633
1 files changed, 323 insertions, 310 deletions
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index be927cc1c..58b001050 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -71,6 +71,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
71 .filter_map(|variant| build_pat(ctx.db(), module, variant)) 71 .filter_map(|variant| build_pat(ctx.db(), module, variant))
72 .filter(|variant_pat| is_variant_missing(&top_lvl_pats, variant_pat)) 72 .filter(|variant_pat| is_variant_missing(&top_lvl_pats, variant_pat))
73 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) 73 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
74 .map(|it| it.clone_for_update())
74 .collect::<Vec<_>>(); 75 .collect::<Vec<_>>();
75 if Some(enum_def) 76 if Some(enum_def)
76 == FamousDefs(&ctx.sema, Some(module.krate())) 77 == FamousDefs(&ctx.sema, Some(module.krate()))
@@ -99,6 +100,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
99 }) 100 })
100 .filter(|variant_pat| is_variant_missing(&top_lvl_pats, variant_pat)) 101 .filter(|variant_pat| is_variant_missing(&top_lvl_pats, variant_pat))
101 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) 102 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
103 .map(|it| it.clone_for_update())
102 .collect() 104 .collect()
103 } else { 105 } else {
104 return None; 106 return None;
@@ -114,10 +116,20 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
114 "Fill match arms", 116 "Fill match arms",
115 target, 117 target,
116 |builder| { 118 |builder| {
117 let new_arm_list = match_arm_list.remove_placeholder(); 119 let new_match_arm_list = match_arm_list.clone_for_update();
118 let n_old_arms = new_arm_list.arms().count(); 120
119 let new_arm_list = new_arm_list.append_arms(missing_arms); 121 let catch_all_arm = new_match_arm_list
120 let first_new_arm = new_arm_list.arms().nth(n_old_arms); 122 .arms()
123 .find(|arm| matches!(arm.pat(), Some(ast::Pat::WildcardPat(_))));
124 if let Some(arm) = catch_all_arm {
125 arm.remove()
126 }
127 let mut first_new_arm = None;
128 for arm in missing_arms {
129 first_new_arm.get_or_insert_with(|| arm.clone());
130 new_match_arm_list.add_arm(arm);
131 }
132
121 let old_range = ctx.sema.original_range(match_arm_list.syntax()).range; 133 let old_range = ctx.sema.original_range(match_arm_list.syntax()).range;
122 match (first_new_arm, ctx.config.snippet_cap) { 134 match (first_new_arm, ctx.config.snippet_cap) {
123 (Some(first_new_arm), Some(cap)) => { 135 (Some(first_new_arm), Some(cap)) => {
@@ -131,10 +143,10 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
131 } 143 }
132 None => Cursor::Before(first_new_arm.syntax()), 144 None => Cursor::Before(first_new_arm.syntax()),
133 }; 145 };
134 let snippet = render_snippet(cap, new_arm_list.syntax(), cursor); 146 let snippet = render_snippet(cap, new_match_arm_list.syntax(), cursor);
135 builder.replace_snippet(cap, old_range, snippet); 147 builder.replace_snippet(cap, old_range, snippet);
136 } 148 }
137 _ => builder.replace(old_range, new_arm_list.to_string()), 149 _ => builder.replace(old_range, new_match_arm_list.to_string()),
138 } 150 }
139 }, 151 },
140 ) 152 )
@@ -263,18 +275,18 @@ mod tests {
263 check_assist_not_applicable( 275 check_assist_not_applicable(
264 fill_match_arms, 276 fill_match_arms,
265 r#" 277 r#"
266 enum A { 278enum A {
267 As, 279 As,
268 Bs{x:i32, y:Option<i32>}, 280 Bs{x:i32, y:Option<i32>},
269 Cs(i32, Option<i32>), 281 Cs(i32, Option<i32>),
270 } 282}
271 fn main() { 283fn main() {
272 match A::As$0 { 284 match A::As$0 {
273 A::As, 285 A::As,
274 A::Bs{x,y:Some(_)} => {} 286 A::Bs{x,y:Some(_)} => {}
275 A::Cs(_, Some(_)) => {} 287 A::Cs(_, Some(_)) => {}
276 } 288 }
277 } 289}
278 "#, 290 "#,
279 ); 291 );
280 } 292 }
@@ -284,13 +296,13 @@ mod tests {
284 check_assist_not_applicable( 296 check_assist_not_applicable(
285 fill_match_arms, 297 fill_match_arms,
286 r#" 298 r#"
287 fn foo(a: bool) { 299fn foo(a: bool) {
288 match a$0 { 300 match a$0 {
289 true => {} 301 true => {}
290 false => {} 302 false => {}
291 } 303 }
292 } 304}
293 "#, 305"#,
294 ) 306 )
295 } 307 }
296 308
@@ -301,11 +313,11 @@ mod tests {
301 check_assist_not_applicable( 313 check_assist_not_applicable(
302 fill_match_arms, 314 fill_match_arms,
303 r#" 315 r#"
304 fn main() { 316fn main() {
305 match (0, false)$0 { 317 match (0, false)$0 {
306 } 318 }
307 } 319}
308 "#, 320"#,
309 ); 321 );
310 } 322 }
311 323
@@ -314,19 +326,19 @@ mod tests {
314 check_assist( 326 check_assist(
315 fill_match_arms, 327 fill_match_arms,
316 r#" 328 r#"
317 fn foo(a: bool) { 329fn foo(a: bool) {
318 match a$0 { 330 match a$0 {
319 } 331 }
320 } 332}
321 "#, 333"#,
322 r#" 334 r#"
323 fn foo(a: bool) { 335fn foo(a: bool) {
324 match a { 336 match a {
325 $0true => {} 337 $0true => {}
326 false => {} 338 false => {}
327 } 339 }
328 } 340}
329 "#, 341"#,
330 ) 342 )
331 } 343 }
332 344
@@ -335,20 +347,20 @@ mod tests {
335 check_assist( 347 check_assist(
336 fill_match_arms, 348 fill_match_arms,
337 r#" 349 r#"
338 fn foo(a: bool) { 350fn foo(a: bool) {
339 match a$0 { 351 match a$0 {
340 true => {} 352 true => {}
341 } 353 }
342 } 354}
343 "#, 355"#,
344 r#" 356 r#"
345 fn foo(a: bool) { 357fn foo(a: bool) {
346 match a { 358 match a {
347 true => {} 359 true => {}
348 $0false => {} 360 $0false => {}
349 } 361 }
350 } 362}
351 "#, 363"#,
352 ) 364 )
353 } 365 }
354 366
@@ -357,15 +369,15 @@ mod tests {
357 check_assist_not_applicable( 369 check_assist_not_applicable(
358 fill_match_arms, 370 fill_match_arms,
359 r#" 371 r#"
360 fn foo(a: bool) { 372fn foo(a: bool) {
361 match (a, a)$0 { 373 match (a, a)$0 {
362 (true, true) => {} 374 (true, true) => {}
363 (true, false) => {} 375 (true, false) => {}
364 (false, true) => {} 376 (false, true) => {}
365 (false, false) => {} 377 (false, false) => {}
366 } 378 }
367 } 379}
368 "#, 380"#,
369 ) 381 )
370 } 382 }
371 383
@@ -374,21 +386,21 @@ mod tests {
374 check_assist( 386 check_assist(
375 fill_match_arms, 387 fill_match_arms,
376 r#" 388 r#"
377 fn foo(a: bool) { 389fn foo(a: bool) {
378 match (a, a)$0 { 390 match (a, a)$0 {
379 } 391 }
380 } 392}
381 "#, 393"#,
382 r#" 394 r#"
383 fn foo(a: bool) { 395fn foo(a: bool) {
384 match (a, a) { 396 match (a, a) {
385 $0(true, true) => {} 397 $0(true, true) => {}
386 (true, false) => {} 398 (true, false) => {}
387 (false, true) => {} 399 (false, true) => {}
388 (false, false) => {} 400 (false, false) => {}
389 } 401 }
390 } 402}
391 "#, 403"#,
392 ) 404 )
393 } 405 }
394 406
@@ -397,22 +409,22 @@ mod tests {
397 check_assist( 409 check_assist(
398 fill_match_arms, 410 fill_match_arms,
399 r#" 411 r#"
400 fn foo(a: bool) { 412fn foo(a: bool) {
401 match (a, a)$0 { 413 match (a, a)$0 {
402 (false, true) => {} 414 (false, true) => {}
403 } 415 }
404 } 416}
405 "#, 417"#,
406 r#" 418 r#"
407 fn foo(a: bool) { 419fn foo(a: bool) {
408 match (a, a) { 420 match (a, a) {
409 (false, true) => {} 421 (false, true) => {}
410 $0(true, true) => {} 422 $0(true, true) => {}
411 (true, false) => {} 423 (true, false) => {}
412 (false, false) => {} 424 (false, false) => {}
413 } 425 }
414 } 426}
415 "#, 427"#,
416 ) 428 )
417 } 429 }
418 430
@@ -421,32 +433,32 @@ mod tests {
421 check_assist( 433 check_assist(
422 fill_match_arms, 434 fill_match_arms,
423 r#" 435 r#"
424 enum A { 436enum A {
425 As, 437 As,
426 Bs { x: i32, y: Option<i32> }, 438 Bs { x: i32, y: Option<i32> },
427 Cs(i32, Option<i32>), 439 Cs(i32, Option<i32>),
428 } 440}
429 fn main() { 441fn main() {
430 match A::As$0 { 442 match A::As$0 {
431 A::Bs { x, y: Some(_) } => {} 443 A::Bs { x, y: Some(_) } => {}
432 A::Cs(_, Some(_)) => {} 444 A::Cs(_, Some(_)) => {}
433 } 445 }
434 } 446}
435 "#, 447"#,
436 r#" 448 r#"
437 enum A { 449enum A {
438 As, 450 As,
439 Bs { x: i32, y: Option<i32> }, 451 Bs { x: i32, y: Option<i32> },
440 Cs(i32, Option<i32>), 452 Cs(i32, Option<i32>),
441 } 453}
442 fn main() { 454fn main() {
443 match A::As { 455 match A::As {
444 A::Bs { x, y: Some(_) } => {} 456 A::Bs { x, y: Some(_) } => {}
445 A::Cs(_, Some(_)) => {} 457 A::Cs(_, Some(_)) => {}
446 $0A::As => {} 458 $0A::As => {}
447 } 459 }
448 } 460}
449 "#, 461"#,
450 ); 462 );
451 } 463 }
452 464
@@ -593,30 +605,30 @@ fn main() {
593 check_assist( 605 check_assist(
594 fill_match_arms, 606 fill_match_arms,
595 r#" 607 r#"
596 enum A { One, Two } 608enum A { One, Two }
597 enum B { One, Two } 609enum B { One, Two }
598 610
599 fn main() { 611fn main() {
600 let a = A::One; 612 let a = A::One;
601 let b = B::One; 613 let b = B::One;
602 match (a$0, b) {} 614 match (a$0, b) {}
603 } 615}
604 "#, 616"#,
605 r#" 617 r#"
606 enum A { One, Two } 618enum A { One, Two }
607 enum B { One, Two } 619enum B { One, Two }
608 620
609 fn main() { 621fn main() {
610 let a = A::One; 622 let a = A::One;
611 let b = B::One; 623 let b = B::One;
612 match (a, b) { 624 match (a, b) {
613 $0(A::One, B::One) => {} 625 $0(A::One, B::One) => {}
614 (A::One, B::Two) => {} 626 (A::One, B::Two) => {}
615 (A::Two, B::One) => {} 627 (A::Two, B::One) => {}
616 (A::Two, B::Two) => {} 628 (A::Two, B::Two) => {}
617 } 629 }
618 } 630}
619 "#, 631"#,
620 ); 632 );
621 } 633 }
622 634
@@ -625,30 +637,30 @@ fn main() {
625 check_assist( 637 check_assist(
626 fill_match_arms, 638 fill_match_arms,
627 r#" 639 r#"
628 enum A { One, Two } 640enum A { One, Two }
629 enum B { One, Two } 641enum B { One, Two }
630 642
631 fn main() { 643fn main() {
632 let a = A::One; 644 let a = A::One;
633 let b = B::One; 645 let b = B::One;
634 match (&a$0, &b) {} 646 match (&a$0, &b) {}
635 } 647}
636 "#, 648"#,
637 r#" 649 r#"
638 enum A { One, Two } 650enum A { One, Two }
639 enum B { One, Two } 651enum B { One, Two }
640 652
641 fn main() { 653fn main() {
642 let a = A::One; 654 let a = A::One;
643 let b = B::One; 655 let b = B::One;
644 match (&a, &b) { 656 match (&a, &b) {
645 $0(A::One, B::One) => {} 657 $0(A::One, B::One) => {}
646 (A::One, B::Two) => {} 658 (A::One, B::Two) => {}
647 (A::Two, B::One) => {} 659 (A::Two, B::One) => {}
648 (A::Two, B::Two) => {} 660 (A::Two, B::Two) => {}
649 } 661 }
650 } 662}
651 "#, 663"#,
652 ); 664 );
653 } 665 }
654 666
@@ -737,20 +749,20 @@ fn main() {
737 check_assist_not_applicable( 749 check_assist_not_applicable(
738 fill_match_arms, 750 fill_match_arms,
739 r#" 751 r#"
740 enum A { One, Two } 752enum A { One, Two }
741 enum B { One, Two } 753enum B { One, Two }
742 754
743 fn main() { 755fn main() {
744 let a = A::One; 756 let a = A::One;
745 let b = B::One; 757 let b = B::One;
746 match (a$0, b) { 758 match (a$0, b) {
747 (A::Two, B::One) => {} 759 (A::Two, B::One) => {}
748 (A::One, B::One) => {} 760 (A::One, B::One) => {}
749 (A::One, B::Two) => {} 761 (A::One, B::Two) => {}
750 (A::Two, B::Two) => {} 762 (A::Two, B::Two) => {}
751 } 763 }
752 } 764}
753 "#, 765"#,
754 ); 766 );
755 } 767 }
756 768
@@ -759,25 +771,25 @@ fn main() {
759 check_assist( 771 check_assist(
760 fill_match_arms, 772 fill_match_arms,
761 r#" 773 r#"
762 enum A { One, Two } 774enum A { One, Two }
763 775
764 fn main() { 776fn main() {
765 let a = A::One; 777 let a = A::One;
766 match (a$0, ) { 778 match (a$0, ) {
767 } 779 }
768 } 780}
769 "#, 781"#,
770 r#" 782 r#"
771 enum A { One, Two } 783enum A { One, Two }
772 784
773 fn main() { 785fn main() {
774 let a = A::One; 786 let a = A::One;
775 match (a, ) { 787 match (a, ) {
776 $0(A::One,) => {} 788 $0(A::One,) => {}
777 (A::Two,) => {} 789 (A::Two,) => {}
778 } 790 }
779 } 791}
780 "#, 792"#,
781 ); 793 );
782 } 794 }
783 795
@@ -786,47 +798,47 @@ fn main() {
786 check_assist( 798 check_assist(
787 fill_match_arms, 799 fill_match_arms,
788 r#" 800 r#"
789 enum A { As } 801enum A { As }
790 802
791 fn foo(a: &A) { 803fn foo(a: &A) {
792 match a$0 { 804 match a$0 {
793 } 805 }
794 } 806}
795 "#, 807"#,
796 r#" 808 r#"
797 enum A { As } 809enum A { As }
798 810
799 fn foo(a: &A) { 811fn foo(a: &A) {
800 match a { 812 match a {
801 $0A::As => {} 813 $0A::As => {}
802 } 814 }
803 } 815}
804 "#, 816"#,
805 ); 817 );
806 818
807 check_assist( 819 check_assist(
808 fill_match_arms, 820 fill_match_arms,
809 r#" 821 r#"
810 enum A { 822enum A {
811 Es { x: usize, y: usize } 823 Es { x: usize, y: usize }
812 } 824}
813 825
814 fn foo(a: &mut A) { 826fn foo(a: &mut A) {
815 match a$0 { 827 match a$0 {
816 } 828 }
817 } 829}
818 "#, 830"#,
819 r#" 831 r#"
820 enum A { 832enum A {
821 Es { x: usize, y: usize } 833 Es { x: usize, y: usize }
822 } 834}
823 835
824 fn foo(a: &mut A) { 836fn foo(a: &mut A) {
825 match a { 837 match a {
826 $0A::Es { x, y } => {} 838 $0A::Es { x, y } => {}
827 } 839 }
828 } 840}
829 "#, 841"#,
830 ); 842 );
831 } 843 }
832 844
@@ -835,12 +847,12 @@ fn main() {
835 check_assist_target( 847 check_assist_target(
836 fill_match_arms, 848 fill_match_arms,
837 r#" 849 r#"
838 enum E { X, Y } 850enum E { X, Y }
839 851
840 fn main() { 852fn main() {
841 match E::X$0 {} 853 match E::X$0 {}
842 } 854}
843 "#, 855"#,
844 "match E::X {}", 856 "match E::X {}",
845 ); 857 );
846 } 858 }
@@ -850,24 +862,24 @@ fn main() {
850 check_assist( 862 check_assist(
851 fill_match_arms, 863 fill_match_arms,
852 r#" 864 r#"
853 enum E { X, Y } 865enum E { X, Y }
854 866
855 fn main() { 867fn main() {
856 match E::X { 868 match E::X {
857 $0_ => {} 869 $0_ => {}
858 } 870 }
859 } 871}
860 "#, 872"#,
861 r#" 873 r#"
862 enum E { X, Y } 874enum E { X, Y }
863 875
864 fn main() { 876fn main() {
865 match E::X { 877 match E::X {
866 $0E::X => {} 878 $0E::X => {}
867 E::Y => {} 879 E::Y => {}
868 } 880 }
869 } 881}
870 "#, 882"#,
871 ); 883 );
872 } 884 }
873 885
@@ -876,26 +888,26 @@ fn main() {
876 check_assist( 888 check_assist(
877 fill_match_arms, 889 fill_match_arms,
878 r#" 890 r#"
879 mod foo { pub enum E { X, Y } } 891mod foo { pub enum E { X, Y } }
880 use foo::E::X; 892use foo::E::X;
881 893
882 fn main() { 894fn main() {
883 match X { 895 match X {
884 $0 896 $0
885 } 897 }
886 } 898}
887 "#, 899"#,
888 r#" 900 r#"
889 mod foo { pub enum E { X, Y } } 901mod foo { pub enum E { X, Y } }
890 use foo::E::X; 902use foo::E::X;
891 903
892 fn main() { 904fn main() {
893 match X { 905 match X {
894 $0X => {} 906 $0X => {}
895 foo::E::Y => {} 907 foo::E::Y => {}
896 } 908 }
897 } 909}
898 "#, 910"#,
899 ); 911 );
900 } 912 }
901 913
@@ -904,26 +916,26 @@ fn main() {
904 check_assist( 916 check_assist(
905 fill_match_arms, 917 fill_match_arms,
906 r#" 918 r#"
907 enum A { One, Two } 919enum A { One, Two }
908 fn foo(a: A) { 920fn foo(a: A) {
909 match a { 921 match a {
910 // foo bar baz$0 922 // foo bar baz$0
911 A::One => {} 923 A::One => {}
912 // This is where the rest should be 924 // This is where the rest should be
913 } 925 }
914 } 926}
915 "#, 927"#,
916 r#" 928 r#"
917 enum A { One, Two } 929enum A { One, Two }
918 fn foo(a: A) { 930fn foo(a: A) {
919 match a { 931 match a {
920 // foo bar baz 932 // foo bar baz
921 A::One => {} 933 A::One => {}
922 // This is where the rest should be 934 $0A::Two => {}
923 $0A::Two => {} 935 // This is where the rest should be
924 } 936 }
925 } 937}
926 "#, 938"#,
927 ); 939 );
928 } 940 }
929 941
@@ -932,23 +944,23 @@ fn main() {
932 check_assist( 944 check_assist(
933 fill_match_arms, 945 fill_match_arms,
934 r#" 946 r#"
935 enum A { One, Two } 947enum A { One, Two }
936 fn foo(a: A) { 948fn foo(a: A) {
937 match a { 949 match a {
938 // foo bar baz$0 950 // foo bar baz$0
939 } 951 }
940 } 952}
941 "#, 953"#,
942 r#" 954 r#"
943 enum A { One, Two } 955enum A { One, Two }
944 fn foo(a: A) { 956fn foo(a: A) {
945 match a { 957 match a {
946 // foo bar baz 958 $0A::One => {}
947 $0A::One => {} 959 A::Two => {}
948 A::Two => {} 960 // foo bar baz
949 } 961 }
950 } 962}
951 "#, 963"#,
952 ); 964 );
953 } 965 }
954 966
@@ -957,22 +969,22 @@ fn main() {
957 check_assist( 969 check_assist(
958 fill_match_arms, 970 fill_match_arms,
959 r#" 971 r#"
960 enum A { One, Two, } 972enum A { One, Two, }
961 fn foo(a: A) { 973fn foo(a: A) {
962 match a$0 { 974 match a$0 {
963 _ => (), 975 _ => (),
964 } 976 }
965 } 977}
966 "#, 978"#,
967 r#" 979 r#"
968 enum A { One, Two, } 980enum A { One, Two, }
969 fn foo(a: A) { 981fn foo(a: A) {
970 match a { 982 match a {
971 $0A::One => {} 983 $0A::One => {}
972 A::Two => {} 984 A::Two => {}
973 } 985 }
974 } 986}
975 "#, 987"#,
976 ); 988 );
977 } 989 }
978 990
@@ -1016,7 +1028,8 @@ enum Test {
1016fn foo(t: Test) { 1028fn foo(t: Test) {
1017 m!(match t$0 {}); 1029 m!(match t$0 {});
1018}"#, 1030}"#,
1019 r#"macro_rules! m { ($expr:expr) => {$expr}} 1031 r#"
1032macro_rules! m { ($expr:expr) => {$expr}}
1020enum Test { 1033enum Test {
1021 A, 1034 A,
1022 B, 1035 B,