aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/diagnostics')
-rw-r--r--crates/ide/src/diagnostics/missing_match_arms.rs99
1 files changed, 52 insertions, 47 deletions
diff --git a/crates/ide/src/diagnostics/missing_match_arms.rs b/crates/ide/src/diagnostics/missing_match_arms.rs
index 6b977fa59..b636489b3 100644
--- a/crates/ide/src/diagnostics/missing_match_arms.rs
+++ b/crates/ide/src/diagnostics/missing_match_arms.rs
@@ -20,9 +20,14 @@ pub(super) fn missing_match_arms(
20pub(super) mod tests { 20pub(super) mod tests {
21 use crate::diagnostics::tests::check_diagnostics; 21 use crate::diagnostics::tests::check_diagnostics;
22 22
23 fn check_diagnostics_no_bails(ra_fixture: &str) {
24 cov_mark::check_count!(validate_match_bailed_out, 0);
25 crate::diagnostics::tests::check_diagnostics(ra_fixture)
26 }
27
23 #[test] 28 #[test]
24 fn empty_tuple() { 29 fn empty_tuple() {
25 check_diagnostics( 30 check_diagnostics_no_bails(
26 r#" 31 r#"
27fn main() { 32fn main() {
28 match () { } 33 match () { }
@@ -40,7 +45,7 @@ fn main() {
40 45
41 #[test] 46 #[test]
42 fn tuple_of_two_empty_tuple() { 47 fn tuple_of_two_empty_tuple() {
43 check_diagnostics( 48 check_diagnostics_no_bails(
44 r#" 49 r#"
45fn main() { 50fn main() {
46 match ((), ()) { } 51 match ((), ()) { }
@@ -54,7 +59,7 @@ fn main() {
54 59
55 #[test] 60 #[test]
56 fn boolean() { 61 fn boolean() {
57 check_diagnostics( 62 check_diagnostics_no_bails(
58 r#" 63 r#"
59fn test_main() { 64fn test_main() {
60 match false { } 65 match false { }
@@ -107,7 +112,7 @@ fn test_main() {
107 112
108 #[test] 113 #[test]
109 fn tuple_of_tuple_and_bools() { 114 fn tuple_of_tuple_and_bools() {
110 check_diagnostics( 115 check_diagnostics_no_bails(
111 r#" 116 r#"
112fn main() { 117fn main() {
113 match (false, ((), false)) {} 118 match (false, ((), false)) {}
@@ -135,7 +140,7 @@ fn main() {
135 140
136 #[test] 141 #[test]
137 fn enums() { 142 fn enums() {
138 check_diagnostics( 143 check_diagnostics_no_bails(
139 r#" 144 r#"
140enum Either { A, B, } 145enum Either { A, B, }
141 146
@@ -163,7 +168,7 @@ fn main() {
163 168
164 #[test] 169 #[test]
165 fn enum_containing_bool() { 170 fn enum_containing_bool() {
166 check_diagnostics( 171 check_diagnostics_no_bails(
167 r#" 172 r#"
168enum Either { A(bool), B } 173enum Either { A(bool), B }
169 174
@@ -196,7 +201,7 @@ fn main() {
196 201
197 #[test] 202 #[test]
198 fn enum_different_sizes() { 203 fn enum_different_sizes() {
199 check_diagnostics( 204 check_diagnostics_no_bails(
200 r#" 205 r#"
201enum Either { A(bool), B(bool, bool) } 206enum Either { A(bool), B(bool, bool) }
202 207
@@ -224,7 +229,7 @@ fn main() {
224 229
225 #[test] 230 #[test]
226 fn tuple_of_enum_no_diagnostic() { 231 fn tuple_of_enum_no_diagnostic() {
227 check_diagnostics( 232 check_diagnostics_no_bails(
228 r#" 233 r#"
229enum Either { A(bool), B(bool, bool) } 234enum Either { A(bool), B(bool, bool) }
230enum Either2 { C, D } 235enum Either2 { C, D }
@@ -243,7 +248,7 @@ fn main() {
243 248
244 #[test] 249 #[test]
245 fn or_pattern_no_diagnostic() { 250 fn or_pattern_no_diagnostic() {
246 check_diagnostics( 251 check_diagnostics_no_bails(
247 r#" 252 r#"
248enum Either {A, B} 253enum Either {A, B}
249 254
@@ -257,6 +262,7 @@ fn main() {
257 262
258 #[test] 263 #[test]
259 fn mismatched_types() { 264 fn mismatched_types() {
265 cov_mark::check_count!(validate_match_bailed_out, 4);
260 // Match statements with arms that don't match the 266 // Match statements with arms that don't match the
261 // expression pattern do not fire this diagnostic. 267 // expression pattern do not fire this diagnostic.
262 check_diagnostics( 268 check_diagnostics(
@@ -267,18 +273,14 @@ enum Either2 { C, D }
267fn main() { 273fn main() {
268 match Either::A { 274 match Either::A {
269 Either2::C => (), 275 Either2::C => (),
270 // ^^^^^^^^^^ Internal: match check bailed out
271 Either2::D => (), 276 Either2::D => (),
272 } 277 }
273 match (true, false) { 278 match (true, false) {
274 (true, false, true) => (), 279 (true, false, true) => (),
275 // ^^^^^^^^^^^^^^^^^^^ Internal: match check bailed out
276 (true) => (), 280 (true) => (),
277 } 281 }
278 match (true, false) { (true,) => {} } 282 match (true, false) { (true,) => {} }
279 // ^^^^^^^ Internal: match check bailed out
280 match (0) { () => () } 283 match (0) { () => () }
281 // ^^ Internal: match check bailed out
282 match Unresolved::Bar { Unresolved::Baz => () } 284 match Unresolved::Bar { Unresolved::Baz => () }
283} 285}
284 "#, 286 "#,
@@ -287,13 +289,12 @@ fn main() {
287 289
288 #[test] 290 #[test]
289 fn mismatched_types_in_or_patterns() { 291 fn mismatched_types_in_or_patterns() {
292 cov_mark::check_count!(validate_match_bailed_out, 2);
290 check_diagnostics( 293 check_diagnostics(
291 r#" 294 r#"
292fn main() { 295fn main() {
293 match false { true | () => {} } 296 match false { true | () => {} }
294 // ^^^^^^^^^ Internal: match check bailed out
295 match (false,) { (true | (),) => {} } 297 match (false,) { (true | (),) => {} }
296 // ^^^^^^^^^^^^ Internal: match check bailed out
297} 298}
298"#, 299"#,
299 ); 300 );
@@ -303,7 +304,7 @@ fn main() {
303 fn malformed_match_arm_tuple_enum_missing_pattern() { 304 fn malformed_match_arm_tuple_enum_missing_pattern() {
304 // We are testing to be sure we don't panic here when the match 305 // We are testing to be sure we don't panic here when the match
305 // arm `Either::B` is missing its pattern. 306 // arm `Either::B` is missing its pattern.
306 check_diagnostics( 307 check_diagnostics_no_bails(
307 r#" 308 r#"
308enum Either { A, B(u32) } 309enum Either { A, B(u32) }
309 310
@@ -319,17 +320,16 @@ fn main() {
319 320
320 #[test] 321 #[test]
321 fn malformed_match_arm_extra_fields() { 322 fn malformed_match_arm_extra_fields() {
323 cov_mark::check_count!(validate_match_bailed_out, 2);
322 check_diagnostics( 324 check_diagnostics(
323 r#" 325 r#"
324enum A { B(isize, isize), C } 326enum A { B(isize, isize), C }
325fn main() { 327fn main() {
326 match A::B(1, 2) { 328 match A::B(1, 2) {
327 A::B(_, _, _) => (), 329 A::B(_, _, _) => (),
328 // ^^^^^^^^^^^^^ Internal: match check bailed out
329 } 330 }
330 match A::B(1, 2) { 331 match A::B(1, 2) {
331 A::C(_) => (), 332 A::C(_) => (),
332 // ^^^^^^^ Internal: match check bailed out
333 } 333 }
334} 334}
335"#, 335"#,
@@ -338,6 +338,7 @@ fn main() {
338 338
339 #[test] 339 #[test]
340 fn expr_diverges() { 340 fn expr_diverges() {
341 cov_mark::check_count!(validate_match_bailed_out, 2);
341 check_diagnostics( 342 check_diagnostics(
342 r#" 343 r#"
343enum Either { A, B } 344enum Either { A, B }
@@ -345,12 +346,10 @@ enum Either { A, B }
345fn main() { 346fn main() {
346 match loop {} { 347 match loop {} {
347 Either::A => (), 348 Either::A => (),
348 // ^^^^^^^^^ Internal: match check bailed out
349 Either::B => (), 349 Either::B => (),
350 } 350 }
351 match loop {} { 351 match loop {} {
352 Either::A => (), 352 Either::A => (),
353 // ^^^^^^^^^ Internal: match check bailed out
354 } 353 }
355 match loop { break Foo::A } { 354 match loop { break Foo::A } {
356 //^^^^^^^^^^^^^^^^^^^^^ missing match arm 355 //^^^^^^^^^^^^^^^^^^^^^ missing match arm
@@ -367,7 +366,7 @@ fn main() {
367 366
368 #[test] 367 #[test]
369 fn expr_partially_diverges() { 368 fn expr_partially_diverges() {
370 check_diagnostics( 369 check_diagnostics_no_bails(
371 r#" 370 r#"
372enum Either<T> { A(T), B } 371enum Either<T> { A(T), B }
373 372
@@ -384,7 +383,7 @@ fn main() -> u32 {
384 383
385 #[test] 384 #[test]
386 fn enum_record() { 385 fn enum_record() {
387 check_diagnostics( 386 check_diagnostics_no_bails(
388 r#" 387 r#"
389enum Either { A { foo: bool }, B } 388enum Either { A { foo: bool }, B }
390 389
@@ -422,7 +421,7 @@ fn main() {
422 421
423 #[test] 422 #[test]
424 fn enum_record_fields_out_of_order() { 423 fn enum_record_fields_out_of_order() {
425 check_diagnostics( 424 check_diagnostics_no_bails(
426 r#" 425 r#"
427enum Either { 426enum Either {
428 A { foo: bool, bar: () }, 427 A { foo: bool, bar: () },
@@ -449,7 +448,7 @@ fn main() {
449 448
450 #[test] 449 #[test]
451 fn enum_record_ellipsis() { 450 fn enum_record_ellipsis() {
452 check_diagnostics( 451 check_diagnostics_no_bails(
453 r#" 452 r#"
454enum Either { 453enum Either {
455 A { foo: bool, bar: bool }, 454 A { foo: bool, bar: bool },
@@ -485,7 +484,7 @@ fn main() {
485 484
486 #[test] 485 #[test]
487 fn enum_tuple_partial_ellipsis() { 486 fn enum_tuple_partial_ellipsis() {
488 check_diagnostics( 487 check_diagnostics_no_bails(
489 r#" 488 r#"
490enum Either { 489enum Either {
491 A(bool, bool, bool, bool), 490 A(bool, bool, bool, bool),
@@ -529,7 +528,7 @@ fn main() {
529 528
530 #[test] 529 #[test]
531 fn never() { 530 fn never() {
532 check_diagnostics( 531 check_diagnostics_no_bails(
533 r#" 532 r#"
534enum Never {} 533enum Never {}
535 534
@@ -549,6 +548,8 @@ fn bang(never: !) {
549 548
550 #[test] 549 #[test]
551 fn unknown_type() { 550 fn unknown_type() {
551 cov_mark::check_count!(validate_match_bailed_out, 1);
552
552 check_diagnostics( 553 check_diagnostics(
553 r#" 554 r#"
554enum Option<T> { Some(T), None } 555enum Option<T> { Some(T), None }
@@ -558,7 +559,6 @@ fn main() {
558 match Option::<Never>::None { 559 match Option::<Never>::None {
559 None => (), 560 None => (),
560 Some(never) => match never {}, 561 Some(never) => match never {},
561 // ^^^^^^^^^^^ Internal: match check bailed out
562 } 562 }
563 match Option::<Never>::None { 563 match Option::<Never>::None {
564 //^^^^^^^^^^^^^^^^^^^^^ missing match arm 564 //^^^^^^^^^^^^^^^^^^^^^ missing match arm
@@ -571,7 +571,7 @@ fn main() {
571 571
572 #[test] 572 #[test]
573 fn tuple_of_bools_with_ellipsis_at_end_missing_arm() { 573 fn tuple_of_bools_with_ellipsis_at_end_missing_arm() {
574 check_diagnostics( 574 check_diagnostics_no_bails(
575 r#" 575 r#"
576fn main() { 576fn main() {
577 match (false, true, false) { 577 match (false, true, false) {
@@ -584,7 +584,7 @@ fn main() {
584 584
585 #[test] 585 #[test]
586 fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() { 586 fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() {
587 check_diagnostics( 587 check_diagnostics_no_bails(
588 r#" 588 r#"
589fn main() { 589fn main() {
590 match (false, true, false) { 590 match (false, true, false) {
@@ -597,7 +597,7 @@ fn main() {
597 597
598 #[test] 598 #[test]
599 fn tuple_of_bools_with_ellipsis_in_middle_missing_arm() { 599 fn tuple_of_bools_with_ellipsis_in_middle_missing_arm() {
600 check_diagnostics( 600 check_diagnostics_no_bails(
601 r#" 601 r#"
602fn main() { 602fn main() {
603 match (false, true, false) { 603 match (false, true, false) {
@@ -610,7 +610,7 @@ fn main() {
610 610
611 #[test] 611 #[test]
612 fn record_struct() { 612 fn record_struct() {
613 check_diagnostics( 613 check_diagnostics_no_bails(
614 r#"struct Foo { a: bool } 614 r#"struct Foo { a: bool }
615fn main(f: Foo) { 615fn main(f: Foo) {
616 match f {} 616 match f {}
@@ -635,7 +635,7 @@ fn main(f: Foo) {
635 635
636 #[test] 636 #[test]
637 fn tuple_struct() { 637 fn tuple_struct() {
638 check_diagnostics( 638 check_diagnostics_no_bails(
639 r#"struct Foo(bool); 639 r#"struct Foo(bool);
640fn main(f: Foo) { 640fn main(f: Foo) {
641 match f {} 641 match f {}
@@ -653,7 +653,7 @@ fn main(f: Foo) {
653 653
654 #[test] 654 #[test]
655 fn unit_struct() { 655 fn unit_struct() {
656 check_diagnostics( 656 check_diagnostics_no_bails(
657 r#"struct Foo; 657 r#"struct Foo;
658fn main(f: Foo) { 658fn main(f: Foo) {
659 match f {} 659 match f {}
@@ -666,7 +666,7 @@ fn main(f: Foo) {
666 666
667 #[test] 667 #[test]
668 fn record_struct_ellipsis() { 668 fn record_struct_ellipsis() {
669 check_diagnostics( 669 check_diagnostics_no_bails(
670 r#"struct Foo { foo: bool, bar: bool } 670 r#"struct Foo { foo: bool, bar: bool }
671fn main(f: Foo) { 671fn main(f: Foo) {
672 match f { Foo { foo: true, .. } => () } 672 match f { Foo { foo: true, .. } => () }
@@ -688,7 +688,7 @@ fn main(f: Foo) {
688 688
689 #[test] 689 #[test]
690 fn internal_or() { 690 fn internal_or() {
691 check_diagnostics( 691 check_diagnostics_no_bails(
692 r#" 692 r#"
693fn main() { 693fn main() {
694 enum Either { A(bool), B } 694 enum Either { A(bool), B }
@@ -703,6 +703,8 @@ fn main() {
703 703
704 #[test] 704 #[test]
705 fn no_panic_at_unimplemented_subpattern_type() { 705 fn no_panic_at_unimplemented_subpattern_type() {
706 cov_mark::check_count!(validate_match_bailed_out, 1);
707
706 check_diagnostics( 708 check_diagnostics(
707 r#" 709 r#"
708struct S { a: char} 710struct S { a: char}
@@ -710,7 +712,6 @@ fn main(v: S) {
710 match v { S{ a } => {} } 712 match v { S{ a } => {} }
711 match v { S{ a: _x } => {} } 713 match v { S{ a: _x } => {} }
712 match v { S{ a: 'a' } => {} } 714 match v { S{ a: 'a' } => {} }
713 //^^^^^^^^^^^ Internal: match check bailed out
714 match v { S{..} => {} } 715 match v { S{..} => {} }
715 match v { _ => {} } 716 match v { _ => {} }
716 match v { } 717 match v { }
@@ -722,7 +723,7 @@ fn main(v: S) {
722 723
723 #[test] 724 #[test]
724 fn binding() { 725 fn binding() {
725 check_diagnostics( 726 check_diagnostics_no_bails(
726 r#" 727 r#"
727fn main() { 728fn main() {
728 match true { 729 match true {
@@ -738,6 +739,8 @@ fn main() {
738 739
739 #[test] 740 #[test]
740 fn binding_ref_has_correct_type() { 741 fn binding_ref_has_correct_type() {
742 cov_mark::check_count!(validate_match_bailed_out, 1);
743
741 // Asserts `PatKind::Binding(ref _x): bool`, not &bool. 744 // Asserts `PatKind::Binding(ref _x): bool`, not &bool.
742 // If that's not true match checking will panic with "incompatible constructors" 745 // If that's not true match checking will panic with "incompatible constructors"
743 // FIXME: make facilities to test this directly like `tests::check_infer(..)` 746 // FIXME: make facilities to test this directly like `tests::check_infer(..)`
@@ -749,7 +752,6 @@ fn main() {
749 // ExprValidator::validate_match(..) checks types of top level patterns incorrecly. 752 // ExprValidator::validate_match(..) checks types of top level patterns incorrecly.
750 match Foo::A { 753 match Foo::A {
751 ref _x => {} 754 ref _x => {}
752 // ^^^^^^ Internal: match check bailed out
753 Foo::A => {} 755 Foo::A => {}
754 } 756 }
755 match (true,) { 757 match (true,) {
@@ -763,7 +765,7 @@ fn main() {
763 765
764 #[test] 766 #[test]
765 fn enum_non_exhaustive() { 767 fn enum_non_exhaustive() {
766 check_diagnostics( 768 check_diagnostics_no_bails(
767 r#" 769 r#"
768//- /lib.rs crate:lib 770//- /lib.rs crate:lib
769#[non_exhaustive] 771#[non_exhaustive]
@@ -799,7 +801,7 @@ fn main() {
799 801
800 #[test] 802 #[test]
801 fn match_guard() { 803 fn match_guard() {
802 check_diagnostics( 804 check_diagnostics_no_bails(
803 r#" 805 r#"
804fn main() { 806fn main() {
805 match true { 807 match true {
@@ -820,7 +822,7 @@ fn main() {
820 #[test] 822 #[test]
821 fn pattern_type_is_of_substitution() { 823 fn pattern_type_is_of_substitution() {
822 cov_mark::check!(match_check_wildcard_expanded_to_substitutions); 824 cov_mark::check!(match_check_wildcard_expanded_to_substitutions);
823 check_diagnostics( 825 check_diagnostics_no_bails(
824 r#" 826 r#"
825struct Foo<T>(T); 827struct Foo<T>(T);
826struct Bar; 828struct Bar;
@@ -835,12 +837,13 @@ fn main() {
835 837
836 #[test] 838 #[test]
837 fn record_struct_no_such_field() { 839 fn record_struct_no_such_field() {
840 cov_mark::check_count!(validate_match_bailed_out, 1);
841
838 check_diagnostics( 842 check_diagnostics(
839 r#" 843 r#"
840struct Foo { } 844struct Foo { }
841fn main(f: Foo) { 845fn main(f: Foo) {
842 match f { Foo { bar } => () } 846 match f { Foo { bar } => () }
843 // ^^^^^^^^^^^ Internal: match check bailed out
844} 847}
845"#, 848"#,
846 ); 849 );
@@ -848,7 +851,7 @@ fn main(f: Foo) {
848 851
849 #[test] 852 #[test]
850 fn match_ergonomics_issue_9095() { 853 fn match_ergonomics_issue_9095() {
851 check_diagnostics( 854 check_diagnostics_no_bails(
852 r#" 855 r#"
853enum Foo<T> { A(T) } 856enum Foo<T> { A(T) }
854fn main() { 857fn main() {
@@ -875,13 +878,14 @@ fn main() {
875 878
876 #[test] 879 #[test]
877 fn integers() { 880 fn integers() {
881 cov_mark::check_count!(validate_match_bailed_out, 1);
882
878 // We don't currently check integer exhaustiveness. 883 // We don't currently check integer exhaustiveness.
879 check_diagnostics( 884 check_diagnostics(
880 r#" 885 r#"
881fn main() { 886fn main() {
882 match 5 { 887 match 5 {
883 10 => (), 888 10 => (),
884 // ^^ Internal: match check bailed out
885 11..20 => (), 889 11..20 => (),
886 } 890 }
887} 891}
@@ -891,12 +895,13 @@ fn main() {
891 895
892 #[test] 896 #[test]
893 fn reference_patterns_at_top_level() { 897 fn reference_patterns_at_top_level() {
898 cov_mark::check_count!(validate_match_bailed_out, 1);
899
894 check_diagnostics( 900 check_diagnostics(
895 r#" 901 r#"
896fn main() { 902fn main() {
897 match &false { 903 match &false {
898 &true => {} 904 &true => {}
899 // ^^^^^ Internal: match check bailed out
900 } 905 }
901} 906}
902 "#, 907 "#,
@@ -905,16 +910,16 @@ fn main() {
905 910
906 #[test] 911 #[test]
907 fn reference_patterns_in_fields() { 912 fn reference_patterns_in_fields() {
913 cov_mark::check_count!(validate_match_bailed_out, 2);
914
908 check_diagnostics( 915 check_diagnostics(
909 r#" 916 r#"
910fn main() { 917fn main() {
911 match (&false,) { 918 match (&false,) {
912 (true,) => {} 919 (true,) => {}
913 // ^^^^^^^ Internal: match check bailed out
914 } 920 }
915 match (&false,) { 921 match (&false,) {
916 (&true,) => {} 922 (&true,) => {}
917 // ^^^^^^^^ Internal: match check bailed out
918 } 923 }
919} 924}
920 "#, 925 "#,