aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/diagnostics/match_check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/diagnostics/match_check.rs')
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs955
1 files changed, 11 insertions, 944 deletions
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index a9a99f57a..a30e42699 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -100,10 +100,19 @@ impl<'a> PatCtxt<'a> {
100 } 100 }
101 101
102 pub(crate) fn lower_pattern(&mut self, pat: hir_def::expr::PatId) -> Pat { 102 pub(crate) fn lower_pattern(&mut self, pat: hir_def::expr::PatId) -> Pat {
103 // FIXME: implement pattern adjustments (implicit pattern dereference; "RFC 2005-match-ergonomics") 103 // XXX(iDawer): Collecting pattern adjustments feels imprecise to me.
104 // When lowering of & and box patterns are implemented this should be tested
105 // in a manner of `match_ergonomics_issue_9095` test.
106 // Pattern adjustment is part of RFC 2005-match-ergonomics.
104 // More info https://github.com/rust-lang/rust/issues/42640#issuecomment-313535089 107 // More info https://github.com/rust-lang/rust/issues/42640#issuecomment-313535089
105 let unadjusted_pat = self.lower_pattern_unadjusted(pat); 108 let unadjusted_pat = self.lower_pattern_unadjusted(pat);
106 unadjusted_pat 109 self.infer.pat_adjustments.get(&pat).map(|it| &**it).unwrap_or_default().iter().rev().fold(
110 unadjusted_pat,
111 |subpattern, ref_ty| Pat {
112 ty: ref_ty.clone(),
113 kind: Box::new(PatKind::Deref { subpattern }),
114 },
115 )
107 } 116 }
108 117
109 fn lower_pattern_unadjusted(&mut self, pat: hir_def::expr::PatId) -> Pat { 118 fn lower_pattern_unadjusted(&mut self, pat: hir_def::expr::PatId) -> Pat {
@@ -355,945 +364,3 @@ impl PatternFoldable for PatKind {
355 } 364 }
356 } 365 }
357} 366}
358
359#[cfg(test)]
360pub(super) mod tests {
361 mod report {
362 use std::any::Any;
363
364 use hir_def::{expr::PatId, DefWithBodyId};
365 use hir_expand::{HirFileId, InFile};
366 use syntax::SyntaxNodePtr;
367
368 use crate::{
369 db::HirDatabase,
370 diagnostics_sink::{Diagnostic, DiagnosticCode, DiagnosticSink},
371 };
372
373 /// In tests, match check bails out loudly.
374 /// This helps to catch incorrect tests that pass due to false negatives.
375 pub(crate) fn report_bail_out(
376 db: &dyn HirDatabase,
377 def: DefWithBodyId,
378 pat: PatId,
379 sink: &mut DiagnosticSink,
380 ) {
381 let (_, source_map) = db.body_with_source_map(def);
382 if let Ok(source_ptr) = source_map.pat_syntax(pat) {
383 let pat_syntax_ptr = source_ptr.value.either(Into::into, Into::into);
384 sink.push(BailedOut { file: source_ptr.file_id, pat_syntax_ptr });
385 }
386 }
387
388 #[derive(Debug)]
389 struct BailedOut {
390 file: HirFileId,
391 pat_syntax_ptr: SyntaxNodePtr,
392 }
393
394 impl Diagnostic for BailedOut {
395 fn code(&self) -> DiagnosticCode {
396 DiagnosticCode("internal:match-check-bailed-out")
397 }
398 fn message(&self) -> String {
399 format!("Internal: match check bailed out")
400 }
401 fn display_source(&self) -> InFile<SyntaxNodePtr> {
402 InFile { file_id: self.file, value: self.pat_syntax_ptr.clone() }
403 }
404 fn as_any(&self) -> &(dyn Any + Send + 'static) {
405 self
406 }
407 }
408 }
409
410 use crate::diagnostics::tests::check_diagnostics;
411
412 pub(crate) use self::report::report_bail_out;
413
414 #[test]
415 fn empty_tuple() {
416 check_diagnostics(
417 r#"
418fn main() {
419 match () { }
420 //^^ Missing match arm
421 match (()) { }
422 //^^^^ Missing match arm
423
424 match () { _ => (), }
425 match () { () => (), }
426 match (()) { (()) => (), }
427}
428"#,
429 );
430 }
431
432 #[test]
433 fn tuple_of_two_empty_tuple() {
434 check_diagnostics(
435 r#"
436fn main() {
437 match ((), ()) { }
438 //^^^^^^^^ Missing match arm
439
440 match ((), ()) { ((), ()) => (), }
441}
442"#,
443 );
444 }
445
446 #[test]
447 fn boolean() {
448 check_diagnostics(
449 r#"
450fn test_main() {
451 match false { }
452 //^^^^^ Missing match arm
453 match false { true => (), }
454 //^^^^^ Missing match arm
455 match (false, true) {}
456 //^^^^^^^^^^^^^ Missing match arm
457 match (false, true) { (true, true) => (), }
458 //^^^^^^^^^^^^^ Missing match arm
459 match (false, true) {
460 //^^^^^^^^^^^^^ Missing match arm
461 (false, true) => (),
462 (false, false) => (),
463 (true, false) => (),
464 }
465 match (false, true) { (true, _x) => (), }
466 //^^^^^^^^^^^^^ Missing match arm
467
468 match false { true => (), false => (), }
469 match (false, true) {
470 (false, _) => (),
471 (true, false) => (),
472 (_, true) => (),
473 }
474 match (false, true) {
475 (true, true) => (),
476 (true, false) => (),
477 (false, true) => (),
478 (false, false) => (),
479 }
480 match (false, true) {
481 (true, _x) => (),
482 (false, true) => (),
483 (false, false) => (),
484 }
485 match (false, true, false) {
486 (false, ..) => (),
487 (true, ..) => (),
488 }
489 match (false, true, false) {
490 (.., false) => (),
491 (.., true) => (),
492 }
493 match (false, true, false) { (..) => (), }
494}
495"#,
496 );
497 }
498
499 #[test]
500 fn tuple_of_tuple_and_bools() {
501 check_diagnostics(
502 r#"
503fn main() {
504 match (false, ((), false)) {}
505 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
506 match (false, ((), false)) { (true, ((), true)) => (), }
507 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
508 match (false, ((), false)) { (true, _) => (), }
509 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
510
511 match (false, ((), false)) {
512 (true, ((), true)) => (),
513 (true, ((), false)) => (),
514 (false, ((), true)) => (),
515 (false, ((), false)) => (),
516 }
517 match (false, ((), false)) {
518 (true, ((), true)) => (),
519 (true, ((), false)) => (),
520 (false, _) => (),
521 }
522}
523"#,
524 );
525 }
526
527 #[test]
528 fn enums() {
529 check_diagnostics(
530 r#"
531enum Either { A, B, }
532
533fn main() {
534 match Either::A { }
535 //^^^^^^^^^ Missing match arm
536 match Either::B { Either::A => (), }
537 //^^^^^^^^^ Missing match arm
538
539 match &Either::B {
540 //^^^^^^^^^^ Missing match arm
541 Either::A => (),
542 }
543
544 match Either::B {
545 Either::A => (), Either::B => (),
546 }
547 match &Either::B {
548 Either::A => (), Either::B => (),
549 }
550}
551"#,
552 );
553 }
554
555 #[test]
556 fn enum_containing_bool() {
557 check_diagnostics(
558 r#"
559enum Either { A(bool), B }
560
561fn main() {
562 match Either::B { }
563 //^^^^^^^^^ Missing match arm
564 match Either::B {
565 //^^^^^^^^^ Missing match arm
566 Either::A(true) => (), Either::B => ()
567 }
568
569 match Either::B {
570 Either::A(true) => (),
571 Either::A(false) => (),
572 Either::B => (),
573 }
574 match Either::B {
575 Either::B => (),
576 _ => (),
577 }
578 match Either::B {
579 Either::A(_) => (),
580 Either::B => (),
581 }
582
583}
584 "#,
585 );
586 }
587
588 #[test]
589 fn enum_different_sizes() {
590 check_diagnostics(
591 r#"
592enum Either { A(bool), B(bool, bool) }
593
594fn main() {
595 match Either::A(false) {
596 //^^^^^^^^^^^^^^^^ Missing match arm
597 Either::A(_) => (),
598 Either::B(false, _) => (),
599 }
600
601 match Either::A(false) {
602 Either::A(_) => (),
603 Either::B(true, _) => (),
604 Either::B(false, _) => (),
605 }
606 match Either::A(false) {
607 Either::A(true) | Either::A(false) => (),
608 Either::B(true, _) => (),
609 Either::B(false, _) => (),
610 }
611}
612"#,
613 );
614 }
615
616 #[test]
617 fn tuple_of_enum_no_diagnostic() {
618 check_diagnostics(
619 r#"
620enum Either { A(bool), B(bool, bool) }
621enum Either2 { C, D }
622
623fn main() {
624 match (Either::A(false), Either2::C) {
625 (Either::A(true), _) | (Either::A(false), _) => (),
626 (Either::B(true, _), Either2::C) => (),
627 (Either::B(false, _), Either2::C) => (),
628 (Either::B(_, _), Either2::D) => (),
629 }
630}
631"#,
632 );
633 }
634
635 #[test]
636 fn or_pattern_no_diagnostic() {
637 check_diagnostics(
638 r#"
639enum Either {A, B}
640
641fn main() {
642 match (Either::A, Either::B) {
643 (Either::A | Either::B, _) => (),
644 }
645}"#,
646 )
647 }
648
649 #[test]
650 fn mismatched_types() {
651 // Match statements with arms that don't match the
652 // expression pattern do not fire this diagnostic.
653 check_diagnostics(
654 r#"
655enum Either { A, B }
656enum Either2 { C, D }
657
658fn main() {
659 match Either::A {
660 Either2::C => (),
661 // ^^^^^^^^^^ Internal: match check bailed out
662 Either2::D => (),
663 }
664 match (true, false) {
665 (true, false, true) => (),
666 // ^^^^^^^^^^^^^^^^^^^ Internal: match check bailed out
667 (true) => (),
668 }
669 match (true, false) { (true,) => {} }
670 // ^^^^^^^ Internal: match check bailed out
671 match (0) { () => () }
672 // ^^ Internal: match check bailed out
673 match Unresolved::Bar { Unresolved::Baz => () }
674}
675 "#,
676 );
677 }
678
679 #[test]
680 fn mismatched_types_in_or_patterns() {
681 check_diagnostics(
682 r#"
683fn main() {
684 match false { true | () => {} }
685 // ^^^^^^^^^ Internal: match check bailed out
686 match (false,) { (true | (),) => {} }
687 // ^^^^^^^^^^^^ Internal: match check bailed out
688}
689"#,
690 );
691 }
692
693 #[test]
694 fn malformed_match_arm_tuple_enum_missing_pattern() {
695 // We are testing to be sure we don't panic here when the match
696 // arm `Either::B` is missing its pattern.
697 check_diagnostics(
698 r#"
699enum Either { A, B(u32) }
700
701fn main() {
702 match Either::A {
703 Either::A => (),
704 Either::B() => (),
705 }
706}
707"#,
708 );
709 }
710
711 #[test]
712 fn malformed_match_arm_extra_fields() {
713 check_diagnostics(
714 r#"
715enum A { B(isize, isize), C }
716fn main() {
717 match A::B(1, 2) {
718 A::B(_, _, _) => (),
719 // ^^^^^^^^^^^^^ Internal: match check bailed out
720 }
721 match A::B(1, 2) {
722 A::C(_) => (),
723 // ^^^^^^^ Internal: match check bailed out
724 }
725}
726"#,
727 );
728 }
729
730 #[test]
731 fn expr_diverges() {
732 check_diagnostics(
733 r#"
734enum Either { A, B }
735
736fn main() {
737 match loop {} {
738 Either::A => (),
739 // ^^^^^^^^^ Internal: match check bailed out
740 Either::B => (),
741 }
742 match loop {} {
743 Either::A => (),
744 // ^^^^^^^^^ Internal: match check bailed out
745 }
746 match loop { break Foo::A } {
747 //^^^^^^^^^^^^^^^^^^^^^ Missing match arm
748 Either::A => (),
749 }
750 match loop { break Foo::A } {
751 Either::A => (),
752 Either::B => (),
753 }
754}
755"#,
756 );
757 }
758
759 #[test]
760 fn expr_partially_diverges() {
761 check_diagnostics(
762 r#"
763enum Either<T> { A(T), B }
764
765fn foo() -> Either<!> { Either::B }
766fn main() -> u32 {
767 match foo() {
768 Either::A(val) => val,
769 Either::B => 0,
770 }
771}
772"#,
773 );
774 }
775
776 #[test]
777 fn enum_record() {
778 check_diagnostics(
779 r#"
780enum Either { A { foo: bool }, B }
781
782fn main() {
783 let a = Either::A { foo: true };
784 match a { }
785 //^ Missing match arm
786 match a { Either::A { foo: true } => () }
787 //^ Missing match arm
788 match a {
789 Either::A { } => (),
790 //^^^^^^^^^ Missing structure fields:
791 // | - foo
792 Either::B => (),
793 }
794 match a {
795 //^ Missing match arm
796 Either::A { } => (),
797 } //^^^^^^^^^ Missing structure fields:
798 // | - foo
799
800 match a {
801 Either::A { foo: true } => (),
802 Either::A { foo: false } => (),
803 Either::B => (),
804 }
805 match a {
806 Either::A { foo: _ } => (),
807 Either::B => (),
808 }
809}
810"#,
811 );
812 }
813
814 #[test]
815 fn enum_record_fields_out_of_order() {
816 check_diagnostics(
817 r#"
818enum Either {
819 A { foo: bool, bar: () },
820 B,
821}
822
823fn main() {
824 let a = Either::A { foo: true, bar: () };
825 match a {
826 //^ Missing match arm
827 Either::A { bar: (), foo: false } => (),
828 Either::A { foo: true, bar: () } => (),
829 }
830
831 match a {
832 Either::A { bar: (), foo: false } => (),
833 Either::A { foo: true, bar: () } => (),
834 Either::B => (),
835 }
836}
837"#,
838 );
839 }
840
841 #[test]
842 fn enum_record_ellipsis() {
843 check_diagnostics(
844 r#"
845enum Either {
846 A { foo: bool, bar: bool },
847 B,
848}
849
850fn main() {
851 let a = Either::B;
852 match a {
853 //^ Missing match arm
854 Either::A { foo: true, .. } => (),
855 Either::B => (),
856 }
857 match a {
858 //^ Missing match arm
859 Either::A { .. } => (),
860 }
861
862 match a {
863 Either::A { foo: true, .. } => (),
864 Either::A { foo: false, .. } => (),
865 Either::B => (),
866 }
867
868 match a {
869 Either::A { .. } => (),
870 Either::B => (),
871 }
872}
873"#,
874 );
875 }
876
877 #[test]
878 fn enum_tuple_partial_ellipsis() {
879 check_diagnostics(
880 r#"
881enum Either {
882 A(bool, bool, bool, bool),
883 B,
884}
885
886fn main() {
887 match Either::B {
888 //^^^^^^^^^ Missing match arm
889 Either::A(true, .., true) => (),
890 Either::A(true, .., false) => (),
891 Either::A(false, .., false) => (),
892 Either::B => (),
893 }
894 match Either::B {
895 //^^^^^^^^^ Missing match arm
896 Either::A(true, .., true) => (),
897 Either::A(true, .., false) => (),
898 Either::A(.., true) => (),
899 Either::B => (),
900 }
901
902 match Either::B {
903 Either::A(true, .., true) => (),
904 Either::A(true, .., false) => (),
905 Either::A(false, .., true) => (),
906 Either::A(false, .., false) => (),
907 Either::B => (),
908 }
909 match Either::B {
910 Either::A(true, .., true) => (),
911 Either::A(true, .., false) => (),
912 Either::A(.., true) => (),
913 Either::A(.., false) => (),
914 Either::B => (),
915 }
916}
917"#,
918 );
919 }
920
921 #[test]
922 fn never() {
923 check_diagnostics(
924 r#"
925enum Never {}
926
927fn enum_(never: Never) {
928 match never {}
929}
930fn enum_ref(never: &Never) {
931 match never {}
932 //^^^^^ Missing match arm
933}
934fn bang(never: !) {
935 match never {}
936}
937"#,
938 );
939 }
940
941 #[test]
942 fn unknown_type() {
943 check_diagnostics(
944 r#"
945enum Option<T> { Some(T), None }
946
947fn main() {
948 // `Never` is deliberately not defined so that it's an uninferred type.
949 match Option::<Never>::None {
950 None => (),
951 Some(never) => match never {},
952 // ^^^^^^^^^^^ Internal: match check bailed out
953 }
954 match Option::<Never>::None {
955 //^^^^^^^^^^^^^^^^^^^^^ Missing match arm
956 Option::Some(_never) => {},
957 }
958}
959"#,
960 );
961 }
962
963 #[test]
964 fn tuple_of_bools_with_ellipsis_at_end_missing_arm() {
965 check_diagnostics(
966 r#"
967fn main() {
968 match (false, true, false) {
969 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
970 (false, ..) => (),
971 }
972}"#,
973 );
974 }
975
976 #[test]
977 fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() {
978 check_diagnostics(
979 r#"
980fn main() {
981 match (false, true, false) {
982 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
983 (.., false) => (),
984 }
985}"#,
986 );
987 }
988
989 #[test]
990 fn tuple_of_bools_with_ellipsis_in_middle_missing_arm() {
991 check_diagnostics(
992 r#"
993fn main() {
994 match (false, true, false) {
995 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
996 (true, .., false) => (),
997 }
998}"#,
999 );
1000 }
1001
1002 #[test]
1003 fn record_struct() {
1004 check_diagnostics(
1005 r#"struct Foo { a: bool }
1006fn main(f: Foo) {
1007 match f {}
1008 //^ Missing match arm
1009 match f { Foo { a: true } => () }
1010 //^ Missing match arm
1011 match &f { Foo { a: true } => () }
1012 //^^ Missing match arm
1013 match f { Foo { a: _ } => () }
1014 match f {
1015 Foo { a: true } => (),
1016 Foo { a: false } => (),
1017 }
1018 match &f {
1019 Foo { a: true } => (),
1020 Foo { a: false } => (),
1021 }
1022}
1023"#,
1024 );
1025 }
1026
1027 #[test]
1028 fn tuple_struct() {
1029 check_diagnostics(
1030 r#"struct Foo(bool);
1031fn main(f: Foo) {
1032 match f {}
1033 //^ Missing match arm
1034 match f { Foo(true) => () }
1035 //^ Missing match arm
1036 match f {
1037 Foo(true) => (),
1038 Foo(false) => (),
1039 }
1040}
1041"#,
1042 );
1043 }
1044
1045 #[test]
1046 fn unit_struct() {
1047 check_diagnostics(
1048 r#"struct Foo;
1049fn main(f: Foo) {
1050 match f {}
1051 //^ Missing match arm
1052 match f { Foo => () }
1053}
1054"#,
1055 );
1056 }
1057
1058 #[test]
1059 fn record_struct_ellipsis() {
1060 check_diagnostics(
1061 r#"struct Foo { foo: bool, bar: bool }
1062fn main(f: Foo) {
1063 match f { Foo { foo: true, .. } => () }
1064 //^ Missing match arm
1065 match f {
1066 //^ Missing match arm
1067 Foo { foo: true, .. } => (),
1068 Foo { bar: false, .. } => ()
1069 }
1070 match f { Foo { .. } => () }
1071 match f {
1072 Foo { foo: true, .. } => (),
1073 Foo { foo: false, .. } => ()
1074 }
1075}
1076"#,
1077 );
1078 }
1079
1080 #[test]
1081 fn internal_or() {
1082 check_diagnostics(
1083 r#"
1084fn main() {
1085 enum Either { A(bool), B }
1086 match Either::B {
1087 //^^^^^^^^^ Missing match arm
1088 Either::A(true | false) => (),
1089 }
1090}
1091"#,
1092 );
1093 }
1094
1095 #[test]
1096 fn no_panic_at_unimplemented_subpattern_type() {
1097 check_diagnostics(
1098 r#"
1099struct S { a: char}
1100fn main(v: S) {
1101 match v { S{ a } => {} }
1102 match v { S{ a: _x } => {} }
1103 match v { S{ a: 'a' } => {} }
1104 //^^^^^^^^^^^ Internal: match check bailed out
1105 match v { S{..} => {} }
1106 match v { _ => {} }
1107 match v { }
1108 //^ Missing match arm
1109}
1110"#,
1111 );
1112 }
1113
1114 #[test]
1115 fn binding() {
1116 check_diagnostics(
1117 r#"
1118fn main() {
1119 match true {
1120 _x @ true => {}
1121 false => {}
1122 }
1123 match true { _x @ true => {} }
1124 //^^^^ Missing match arm
1125}
1126"#,
1127 );
1128 }
1129
1130 #[test]
1131 fn binding_ref_has_correct_type() {
1132 // Asserts `PatKind::Binding(ref _x): bool`, not &bool.
1133 // If that's not true match checking will panic with "incompatible constructors"
1134 // FIXME: make facilities to test this directly like `tests::check_infer(..)`
1135 check_diagnostics(
1136 r#"
1137enum Foo { A }
1138fn main() {
1139 // FIXME: this should not bail out but current behavior is such as the old algorithm.
1140 // ExprValidator::validate_match(..) checks types of top level patterns incorrecly.
1141 match Foo::A {
1142 ref _x => {}
1143 // ^^^^^^ Internal: match check bailed out
1144 Foo::A => {}
1145 }
1146 match (true,) {
1147 (ref _x,) => {}
1148 (true,) => {}
1149 }
1150}
1151"#,
1152 );
1153 }
1154
1155 #[test]
1156 fn enum_non_exhaustive() {
1157 check_diagnostics(
1158 r#"
1159//- /lib.rs crate:lib
1160#[non_exhaustive]
1161pub enum E { A, B }
1162fn _local() {
1163 match E::A { _ => {} }
1164 match E::A {
1165 E::A => {}
1166 E::B => {}
1167 }
1168 match E::A {
1169 E::A | E::B => {}
1170 }
1171}
1172
1173//- /main.rs crate:main deps:lib
1174use lib::E;
1175fn main() {
1176 match E::A { _ => {} }
1177 match E::A {
1178 //^^^^ Missing match arm
1179 E::A => {}
1180 E::B => {}
1181 }
1182 match E::A {
1183 //^^^^ Missing match arm
1184 E::A | E::B => {}
1185 }
1186}
1187"#,
1188 );
1189 }
1190
1191 #[test]
1192 fn match_guard() {
1193 check_diagnostics(
1194 r#"
1195fn main() {
1196 match true {
1197 true if false => {}
1198 true => {}
1199 false => {}
1200 }
1201 match true {
1202 //^^^^ Missing match arm
1203 true if false => {}
1204 false => {}
1205}
1206"#,
1207 );
1208 }
1209
1210 #[test]
1211 fn pattern_type_is_of_substitution() {
1212 cov_mark::check!(match_check_wildcard_expanded_to_substitutions);
1213 check_diagnostics(
1214 r#"
1215struct Foo<T>(T);
1216struct Bar;
1217fn main() {
1218 match Foo(Bar) {
1219 _ | Foo(Bar) => {}
1220 }
1221}
1222"#,
1223 );
1224 }
1225
1226 #[test]
1227 fn record_struct_no_such_field() {
1228 check_diagnostics(
1229 r#"
1230struct Foo { }
1231fn main(f: Foo) {
1232 match f { Foo { bar } => () }
1233 // ^^^^^^^^^^^ Internal: match check bailed out
1234}
1235"#,
1236 );
1237 }
1238
1239 mod false_negatives {
1240 //! The implementation of match checking here is a work in progress. As we roll this out, we
1241 //! prefer false negatives to false positives (ideally there would be no false positives). This
1242 //! test module should document known false negatives. Eventually we will have a complete
1243 //! implementation of match checking and this module will be empty.
1244 //!
1245 //! The reasons for documenting known false negatives:
1246 //!
1247 //! 1. It acts as a backlog of work that can be done to improve the behavior of the system.
1248 //! 2. It ensures the code doesn't panic when handling these cases.
1249 use super::*;
1250
1251 #[test]
1252 fn integers() {
1253 // We don't currently check integer exhaustiveness.
1254 check_diagnostics(
1255 r#"
1256fn main() {
1257 match 5 {
1258 10 => (),
1259 // ^^ Internal: match check bailed out
1260 11..20 => (),
1261 }
1262}
1263"#,
1264 );
1265 }
1266
1267 #[test]
1268 fn reference_patterns_at_top_level() {
1269 check_diagnostics(
1270 r#"
1271fn main() {
1272 match &false {
1273 &true => {}
1274 // ^^^^^ Internal: match check bailed out
1275 }
1276}
1277 "#,
1278 );
1279 }
1280
1281 #[test]
1282 fn reference_patterns_in_fields() {
1283 check_diagnostics(
1284 r#"
1285fn main() {
1286 match (&false,) {
1287 (true,) => {}
1288 // ^^^^^^^ Internal: match check bailed out
1289 }
1290 match (&false,) {
1291 (&true,) => {}
1292 // ^^^^^^^^ Internal: match check bailed out
1293 }
1294}
1295 "#,
1296 );
1297 }
1298 }
1299}