aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs25
-rw-r--r--crates/ra_hir_ty/src/diagnostics/expr.rs169
-rw-r--r--crates/ra_hir_ty/src/diagnostics/match_check.rs1561
-rw-r--r--crates/ra_hir_ty/src/test_db.rs23
4 files changed, 511 insertions, 1267 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 3623b8569..3016ca3bd 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -244,3 +244,28 @@ impl AstDiagnostic for MismatchedArgCount {
244 ast::CallExpr::cast(node).unwrap() 244 ast::CallExpr::cast(node).unwrap()
245 } 245 }
246} 246}
247
248#[cfg(test)]
249fn check_diagnostics(ra_fixture: &str) {
250 use ra_db::{fixture::WithFixture, FileId};
251 use ra_syntax::TextRange;
252 use rustc_hash::FxHashMap;
253
254 use crate::test_db::TestDB;
255
256 let db = TestDB::with_files(ra_fixture);
257 let annotations = db.extract_annotations();
258
259 let mut actual: FxHashMap<FileId, Vec<(TextRange, String)>> = FxHashMap::default();
260 db.diag(|d| {
261 // FXIME: macros...
262 let file_id = d.source().file_id.original_file(&db);
263 let range = d.syntax_node(&db).text_range();
264 // FIXME: support multi-line messages in annotations
265 let message = d.message().lines().next().unwrap().to_owned();
266 actual.entry(file_id).or_default().push((range, message));
267 });
268 actual.values_mut().for_each(|diags| diags.sort_by_key(|it| it.0.start()));
269
270 assert_eq!(annotations, actual);
271}
diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs
index 239be779f..277ace180 100644
--- a/crates/ra_hir_ty/src/diagnostics/expr.rs
+++ b/crates/ra_hir_ty/src/diagnostics/expr.rs
@@ -376,146 +376,117 @@ pub fn record_pattern_missing_fields(
376 376
377#[cfg(test)] 377#[cfg(test)]
378mod tests { 378mod tests {
379 use expect::{expect, Expect}; 379 use crate::diagnostics::check_diagnostics;
380 use ra_db::fixture::WithFixture;
381
382 use crate::{diagnostics::MismatchedArgCount, test_db::TestDB};
383
384 fn check_diagnostic(ra_fixture: &str, expect: Expect) {
385 let msg = TestDB::with_single_file(ra_fixture).0.diagnostic::<MismatchedArgCount>().0;
386 expect.assert_eq(&msg);
387 }
388
389 fn check_no_diagnostic(ra_fixture: &str) {
390 let (s, diagnostic_count) =
391 TestDB::with_single_file(ra_fixture).0.diagnostic::<MismatchedArgCount>();
392
393 assert_eq!(0, diagnostic_count, "expected no diagnostic, found one: {}", s);
394 }
395 380
396 #[test] 381 #[test]
397 fn simple_free_fn_zero() { 382 fn simple_free_fn_zero() {
398 check_diagnostic( 383 check_diagnostics(
399 r" 384 r#"
400 fn zero() {} 385fn zero() {}
401 fn f() { zero(1); } 386fn f() { zero(1); }
402 ", 387 //^^^^^^^ Expected 0 arguments, found 1
403 expect![["\"zero(1)\": Expected 0 arguments, found 1\n"]], 388"#,
404 ); 389 );
405 390
406 check_no_diagnostic( 391 check_diagnostics(
407 r" 392 r#"
408 fn zero() {} 393fn zero() {}
409 fn f() { zero(); } 394fn f() { zero(); }
410 ", 395"#,
411 ); 396 );
412 } 397 }
413 398
414 #[test] 399 #[test]
415 fn simple_free_fn_one() { 400 fn simple_free_fn_one() {
416 check_diagnostic( 401 check_diagnostics(
417 r" 402 r#"
418 fn one(arg: u8) {} 403fn one(arg: u8) {}
419 fn f() { one(); } 404fn f() { one(); }
420 ", 405 //^^^^^ Expected 1 argument, found 0
421 expect![["\"one()\": Expected 1 argument, found 0\n"]], 406"#,
422 ); 407 );
423 408
424 check_no_diagnostic( 409 check_diagnostics(
425 r" 410 r#"
426 fn one(arg: u8) {} 411fn one(arg: u8) {}
427 fn f() { one(1); } 412fn f() { one(1); }
428 ", 413"#,
429 ); 414 );
430 } 415 }
431 416
432 #[test] 417 #[test]
433 fn method_as_fn() { 418 fn method_as_fn() {
434 check_diagnostic( 419 check_diagnostics(
435 r" 420 r#"
436 struct S; 421struct S;
437 impl S { 422impl S { fn method(&self) {} }
438 fn method(&self) {} 423
439 } 424fn f() {
440 425 S::method();
441 fn f() { 426} //^^^^^^^^^^^ Expected 1 argument, found 0
442 S::method(); 427"#,
443 }
444 ",
445 expect![["\"S::method()\": Expected 1 argument, found 0\n"]],
446 ); 428 );
447 429
448 check_no_diagnostic( 430 check_diagnostics(
449 r" 431 r#"
450 struct S; 432struct S;
451 impl S { 433impl S { fn method(&self) {} }
452 fn method(&self) {}
453 }
454 434
455 fn f() { 435fn f() {
456 S::method(&S); 436 S::method(&S);
457 S.method(); 437 S.method();
458 } 438}
459 ", 439"#,
460 ); 440 );
461 } 441 }
462 442
463 #[test] 443 #[test]
464 fn method_with_arg() { 444 fn method_with_arg() {
465 check_diagnostic( 445 check_diagnostics(
466 r" 446 r#"
467 struct S; 447struct S;
468 impl S { 448impl S { fn method(&self, arg: u8) {} }
469 fn method(&self, arg: u8) {}
470 }
471 449
472 fn f() { 450 fn f() {
473 S.method(); 451 S.method();
474 } 452 } //^^^^^^^^^^ Expected 1 argument, found 0
475 ", 453 "#,
476 expect![["\"S.method()\": Expected 1 argument, found 0\n"]],
477 ); 454 );
478 455
479 check_no_diagnostic( 456 check_diagnostics(
480 r" 457 r#"
481 struct S; 458struct S;
482 impl S { 459impl S { fn method(&self, arg: u8) {} }
483 fn method(&self, arg: u8) {}
484 }
485 460
486 fn f() { 461fn f() {
487 S::method(&S, 0); 462 S::method(&S, 0);
488 S.method(1); 463 S.method(1);
489 } 464}
490 ", 465"#,
491 ); 466 );
492 } 467 }
493 468
494 #[test] 469 #[test]
495 fn tuple_struct() { 470 fn tuple_struct() {
496 check_diagnostic( 471 check_diagnostics(
497 r" 472 r#"
498 struct Tup(u8, u16); 473struct Tup(u8, u16);
499 fn f() { 474fn f() {
500 Tup(0); 475 Tup(0);
501 } 476} //^^^^^^ Expected 2 arguments, found 1
502 ", 477"#,
503 expect![["\"Tup(0)\": Expected 2 arguments, found 1\n"]],
504 ) 478 )
505 } 479 }
506 480
507 #[test] 481 #[test]
508 fn enum_variant() { 482 fn enum_variant() {
509 check_diagnostic( 483 check_diagnostics(
510 r" 484 r#"
511 enum En { 485enum En { Variant(u8, u16), }
512 Variant(u8, u16), 486fn f() {
513 } 487 En::Variant(0);
514 fn f() { 488} //^^^^^^^^^^^^^^ Expected 2 arguments, found 1
515 En::Variant(0); 489"#,
516 }
517 ",
518 expect![["\"En::Variant(0)\": Expected 2 arguments, found 1\n"]],
519 ) 490 )
520 } 491 }
521} 492}
diff --git a/crates/ra_hir_ty/src/diagnostics/match_check.rs b/crates/ra_hir_ty/src/diagnostics/match_check.rs
index 899025a87..ba48b51b5 100644
--- a/crates/ra_hir_ty/src/diagnostics/match_check.rs
+++ b/crates/ra_hir_ty/src/diagnostics/match_check.rs
@@ -41,9 +41,9 @@
41//! ```ignore 41//! ```ignore
42//! // x: (Option<bool>, Result<()>) 42//! // x: (Option<bool>, Result<()>)
43//! match x { 43//! match x {
44//! (Some(true), _) => {} 44//! (Some(true), _) => (),
45//! (None, Err(())) => {} 45//! (None, Err(())) => (),
46//! (None, Err(_)) => {} 46//! (None, Err(_)) => (),
47//! } 47//! }
48//! ``` 48//! ```
49//! 49//!
@@ -837,685 +837,251 @@ fn enum_variant_matches(cx: &MatchCheckCtx, pat_id: PatId, enum_variant_id: Enum
837 837
838#[cfg(test)] 838#[cfg(test)]
839mod tests { 839mod tests {
840 use insta::assert_snapshot; 840 use crate::diagnostics::check_diagnostics;
841 use ra_db::fixture::WithFixture;
842
843 use crate::{diagnostics::MissingMatchArms, test_db::TestDB};
844
845 fn check_diagnostic_message(ra_fixture: &str) -> String {
846 TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>().0
847 }
848
849 fn check_diagnostic(ra_fixture: &str) {
850 let diagnostic_count =
851 TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>().1;
852
853 assert_eq!(1, diagnostic_count, "no diagnostic reported");
854 }
855
856 fn check_no_diagnostic(ra_fixture: &str) {
857 let (s, diagnostic_count) =
858 TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>();
859
860 assert_eq!(0, diagnostic_count, "expected no diagnostic, found one: {}", s);
861 }
862
863 #[test]
864 fn empty_tuple_no_arms_diagnostic_message() {
865 assert_snapshot!(
866 check_diagnostic_message(r"
867 fn test_fn() {
868 match () {
869 }
870 }
871 "),
872 @"\"()\": Missing match arm\n"
873 );
874 }
875
876 #[test]
877 fn empty_tuple_no_arms() {
878 check_diagnostic(
879 r"
880 fn test_fn() {
881 match () {
882 }
883 }
884 ",
885 );
886 }
887
888 #[test]
889 fn empty_tuple_wild() {
890 check_no_diagnostic(
891 r"
892 fn test_fn() {
893 match () {
894 _ => {}
895 }
896 }
897 ",
898 );
899 }
900 841
901 #[test] 842 #[test]
902 fn empty_tuple_no_diagnostic() { 843 fn empty_tuple() {
903 check_no_diagnostic( 844 check_diagnostics(
904 r" 845 r#"
905 fn test_fn() { 846fn main() {
906 match () { 847 match () { }
907 () => {} 848 //^^ Missing match arm
908 } 849 match (()) { }
909 } 850 //^^^^ Missing match arm
910 ",
911 );
912 }
913
914 #[test]
915 fn tuple_of_empty_tuple_no_arms() {
916 check_diagnostic(
917 r"
918 fn test_fn() {
919 match (()) {
920 }
921 }
922 ",
923 );
924 }
925 851
926 #[test] 852 match () { _ => (), }
927 fn tuple_of_empty_tuple_no_diagnostic() { 853 match () { () => (), }
928 check_no_diagnostic( 854 match (()) { (()) => (), }
929 r" 855}
930 fn test_fn() { 856"#,
931 match (()) {
932 (()) => {}
933 }
934 }
935 ",
936 );
937 }
938
939 #[test]
940 fn tuple_of_two_empty_tuple_no_arms() {
941 check_diagnostic(
942 r"
943 fn test_fn() {
944 match ((), ()) {
945 }
946 }
947 ",
948 );
949 }
950
951 #[test]
952 fn tuple_of_two_empty_tuple_no_diagnostic() {
953 check_no_diagnostic(
954 r"
955 fn test_fn() {
956 match ((), ()) {
957 ((), ()) => {}
958 }
959 }
960 ",
961 );
962 }
963
964 #[test]
965 fn bool_no_arms() {
966 check_diagnostic(
967 r"
968 fn test_fn() {
969 match false {
970 }
971 }
972 ",
973 );
974 }
975
976 #[test]
977 fn bool_missing_arm() {
978 check_diagnostic(
979 r"
980 fn test_fn() {
981 match false {
982 true => {}
983 }
984 }
985 ",
986 );
987 }
988
989 #[test]
990 fn bool_no_diagnostic() {
991 check_no_diagnostic(
992 r"
993 fn test_fn() {
994 match false {
995 true => {}
996 false => {}
997 }
998 }
999 ",
1000 );
1001 }
1002
1003 #[test]
1004 fn tuple_of_bools_no_arms() {
1005 check_diagnostic(
1006 r"
1007 fn test_fn() {
1008 match (false, true) {
1009 }
1010 }
1011 ",
1012 );
1013 }
1014
1015 #[test]
1016 fn tuple_of_bools_missing_arms() {
1017 check_diagnostic(
1018 r"
1019 fn test_fn() {
1020 match (false, true) {
1021 (true, true) => {},
1022 }
1023 }
1024 ",
1025 );
1026 }
1027
1028 #[test]
1029 fn tuple_of_bools_missing_arm() {
1030 check_diagnostic(
1031 r"
1032 fn test_fn() {
1033 match (false, true) {
1034 (false, true) => {},
1035 (false, false) => {},
1036 (true, false) => {},
1037 }
1038 }
1039 ",
1040 );
1041 }
1042
1043 #[test]
1044 fn tuple_of_bools_with_wilds() {
1045 check_no_diagnostic(
1046 r"
1047 fn test_fn() {
1048 match (false, true) {
1049 (false, _) => {},
1050 (true, false) => {},
1051 (_, true) => {},
1052 }
1053 }
1054 ",
1055 ); 857 );
1056 } 858 }
1057 859
1058 #[test] 860 #[test]
1059 fn tuple_of_bools_no_diagnostic() { 861 fn tuple_of_two_empty_tuple() {
1060 check_no_diagnostic( 862 check_diagnostics(
1061 r" 863 r#"
1062 fn test_fn() { 864fn main() {
1063 match (false, true) { 865 match ((), ()) { }
1064 (true, true) => {}, 866 //^^^^^^^^ Missing match arm
1065 (true, false) => {},
1066 (false, true) => {},
1067 (false, false) => {},
1068 }
1069 }
1070 ",
1071 );
1072 }
1073 867
1074 #[test] 868 match ((), ()) { ((), ()) => (), }
1075 fn tuple_of_bools_binding_missing_arms() { 869}
1076 check_diagnostic( 870"#,
1077 r" 871 );
1078 fn test_fn() { 872 }
1079 match (false, true) { 873
1080 (true, _x) => {}, 874 #[test]
1081 } 875 fn boolean() {
1082 } 876 check_diagnostics(
1083 ", 877 r#"
1084 ); 878fn test_main() {
1085 } 879 match false { }
1086 880 //^^^^^ Missing match arm
1087 #[test] 881 match false { true => (), }
1088 fn tuple_of_bools_binding_no_diagnostic() { 882 //^^^^^ Missing match arm
1089 check_no_diagnostic( 883 match (false, true) {}
1090 r" 884 //^^^^^^^^^^^^^ Missing match arm
1091 fn test_fn() { 885 match (false, true) { (true, true) => (), }
1092 match (false, true) { 886 //^^^^^^^^^^^^^ Missing match arm
1093 (true, _x) => {}, 887 match (false, true) {
1094 (false, true) => {}, 888 //^^^^^^^^^^^^^ Missing match arm
1095 (false, false) => {}, 889 (false, true) => (),
1096 } 890 (false, false) => (),
1097 } 891 (true, false) => (),
1098 ", 892 }
893 match (false, true) { (true, _x) => (), }
894 //^^^^^^^^^^^^^ Missing match arm
895
896 match false { true => (), false => (), }
897 match (false, true) {
898 (false, _) => (),
899 (true, false) => (),
900 (_, true) => (),
901 }
902 match (false, true) {
903 (true, true) => (),
904 (true, false) => (),
905 (false, true) => (),
906 (false, false) => (),
907 }
908 match (false, true) {
909 (true, _x) => (),
910 (false, true) => (),
911 (false, false) => (),
912 }
913 match (false, true, false) {
914 (false, ..) => (),
915 (true, ..) => (),
916 }
917 match (false, true, false) {
918 (.., false) => (),
919 (.., true) => (),
920 }
921 match (false, true, false) { (..) => (), }
922}
923"#,
1099 ); 924 );
1100 } 925 }
1101 926
1102 #[test] 927 #[test]
1103 fn tuple_of_bools_with_ellipsis_at_end_no_diagnostic() { 928 fn tuple_of_tuple_and_bools() {
1104 check_no_diagnostic( 929 check_diagnostics(
1105 r" 930 r#"
1106 fn test_fn() { 931fn main() {
1107 match (false, true, false) { 932 match (false, ((), false)) {}
1108 (false, ..) => {}, 933 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
1109 (true, ..) => {}, 934 match (false, ((), false)) { (true, ((), true)) => (), }
1110 } 935 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
1111 } 936 match (false, ((), false)) { (true, _) => (), }
1112 ", 937 //^^^^^^^^^^^^^^^^^^^^ Missing match arm
1113 );
1114 }
1115 938
1116 #[test] 939 match (false, ((), false)) {
1117 fn tuple_of_bools_with_ellipsis_at_beginning_no_diagnostic() { 940 (true, ((), true)) => (),
1118 check_no_diagnostic( 941 (true, ((), false)) => (),
1119 r" 942 (false, ((), true)) => (),
1120 fn test_fn() { 943 (false, ((), false)) => (),
1121 match (false, true, false) {
1122 (.., false) => {},
1123 (.., true) => {},
1124 }
1125 }
1126 ",
1127 );
1128 } 944 }
1129 945 match (false, ((), false)) {
1130 #[test] 946 (true, ((), true)) => (),
1131 fn tuple_of_bools_with_ellipsis_no_diagnostic() { 947 (true, ((), false)) => (),
1132 check_no_diagnostic( 948 (false, _) => (),
1133 r"
1134 fn test_fn() {
1135 match (false, true, false) {
1136 (..) => {},
1137 }
1138 }
1139 ",
1140 );
1141 } 949 }
1142 950}
1143 #[test] 951"#,
1144 fn tuple_of_tuple_and_bools_no_arms() {
1145 check_diagnostic(
1146 r"
1147 fn test_fn() {
1148 match (false, ((), false)) {
1149 }
1150 }
1151 ",
1152 ); 952 );
1153 } 953 }
1154 954
1155 #[test] 955 #[test]
1156 fn tuple_of_tuple_and_bools_missing_arms() { 956 fn enums() {
1157 check_diagnostic( 957 check_diagnostics(
1158 r" 958 r#"
1159 fn test_fn() { 959enum Either { A, B, }
1160 match (false, ((), false)) {
1161 (true, ((), true)) => {},
1162 }
1163 }
1164 ",
1165 );
1166 }
1167 960
1168 #[test] 961fn main() {
1169 fn tuple_of_tuple_and_bools_no_diagnostic() { 962 match Either::A { }
1170 check_no_diagnostic( 963 //^^^^^^^^^ Missing match arm
1171 r" 964 match Either::B { Either::A => (), }
1172 fn test_fn() { 965 //^^^^^^^^^ Missing match arm
1173 match (false, ((), false)) {
1174 (true, ((), true)) => {},
1175 (true, ((), false)) => {},
1176 (false, ((), true)) => {},
1177 (false, ((), false)) => {},
1178 }
1179 }
1180 ",
1181 );
1182 }
1183 966
1184 #[test] 967 match &Either::B {
1185 fn tuple_of_tuple_and_bools_wildcard_missing_arms() { 968 //^^^^^^^^^^ Missing match arm
1186 check_diagnostic( 969 Either::A => (),
1187 r"
1188 fn test_fn() {
1189 match (false, ((), false)) {
1190 (true, _) => {},
1191 }
1192 }
1193 ",
1194 );
1195 } 970 }
1196 971
1197 #[test] 972 match Either::B {
1198 fn tuple_of_tuple_and_bools_wildcard_no_diagnostic() { 973 Either::A => (), Either::B => (),
1199 check_no_diagnostic(
1200 r"
1201 fn test_fn() {
1202 match (false, ((), false)) {
1203 (true, ((), true)) => {},
1204 (true, ((), false)) => {},
1205 (false, _) => {},
1206 }
1207 }
1208 ",
1209 );
1210 } 974 }
1211 975 match &Either::B {
1212 #[test] 976 Either::A => (), Either::B => (),
1213 fn enum_no_arms() {
1214 check_diagnostic(
1215 r"
1216 enum Either {
1217 A,
1218 B,
1219 }
1220 fn test_fn() {
1221 match Either::A {
1222 }
1223 }
1224 ",
1225 );
1226 } 977 }
1227 978}
1228 #[test] 979"#,
1229 fn enum_missing_arms() {
1230 check_diagnostic(
1231 r"
1232 enum Either {
1233 A,
1234 B,
1235 }
1236 fn test_fn() {
1237 match Either::B {
1238 Either::A => {},
1239 }
1240 }
1241 ",
1242 ); 980 );
1243 } 981 }
1244 982
1245 #[test] 983 #[test]
1246 fn enum_no_diagnostic() { 984 fn enum_containing_bool() {
1247 check_no_diagnostic( 985 check_diagnostics(
1248 r" 986 r#"
1249 enum Either { 987enum Either { A(bool), B }
1250 A,
1251 B,
1252 }
1253 fn test_fn() {
1254 match Either::B {
1255 Either::A => {},
1256 Either::B => {},
1257 }
1258 }
1259 ",
1260 );
1261 }
1262 988
1263 #[test] 989fn main() {
1264 fn enum_ref_missing_arms() { 990 match Either::B { }
1265 check_diagnostic( 991 //^^^^^^^^^ Missing match arm
1266 r" 992 match Either::B {
1267 enum Either { 993 //^^^^^^^^^ Missing match arm
1268 A, 994 Either::A(true) => (), Either::B => ()
1269 B,
1270 }
1271 fn test_fn() {
1272 match &Either::B {
1273 Either::A => {},
1274 }
1275 }
1276 ",
1277 );
1278 } 995 }
1279 996
1280 #[test] 997 match Either::B {
1281 fn enum_ref_no_diagnostic() { 998 Either::A(true) => (),
1282 check_no_diagnostic( 999 Either::A(false) => (),
1283 r" 1000 Either::B => (),
1284 enum Either {
1285 A,
1286 B,
1287 }
1288 fn test_fn() {
1289 match &Either::B {
1290 Either::A => {},
1291 Either::B => {},
1292 }
1293 }
1294 ",
1295 );
1296 } 1001 }
1297 1002 match Either::B {
1298 #[test] 1003 Either::B => (),
1299 fn enum_containing_bool_no_arms() { 1004 _ => (),
1300 check_diagnostic(
1301 r"
1302 enum Either {
1303 A(bool),
1304 B,
1305 }
1306 fn test_fn() {
1307 match Either::B {
1308 }
1309 }
1310 ",
1311 );
1312 } 1005 }
1313 1006 match Either::B {
1314 #[test] 1007 Either::A(_) => (),
1315 fn enum_containing_bool_missing_arms() { 1008 Either::B => (),
1316 check_diagnostic(
1317 r"
1318 enum Either {
1319 A(bool),
1320 B,
1321 }
1322 fn test_fn() {
1323 match Either::B {
1324 Either::A(true) => (),
1325 Either::B => (),
1326 }
1327 }
1328 ",
1329 );
1330 } 1009 }
1331 1010
1332 #[test] 1011}
1333 fn enum_containing_bool_no_diagnostic() { 1012 "#,
1334 check_no_diagnostic(
1335 r"
1336 enum Either {
1337 A(bool),
1338 B,
1339 }
1340 fn test_fn() {
1341 match Either::B {
1342 Either::A(true) => (),
1343 Either::A(false) => (),
1344 Either::B => (),
1345 }
1346 }
1347 ",
1348 ); 1013 );
1349 } 1014 }
1350 1015
1351 #[test] 1016 #[test]
1352 fn enum_containing_bool_with_wild_no_diagnostic() { 1017 fn enum_different_sizes() {
1353 check_no_diagnostic( 1018 check_diagnostics(
1354 r" 1019 r#"
1355 enum Either { 1020enum Either { A(bool), B(bool, bool) }
1356 A(bool),
1357 B,
1358 }
1359 fn test_fn() {
1360 match Either::B {
1361 Either::B => (),
1362 _ => (),
1363 }
1364 }
1365 ",
1366 );
1367 }
1368 1021
1369 #[test] 1022fn main() {
1370 fn enum_containing_bool_with_wild_2_no_diagnostic() { 1023 match Either::A(false) {
1371 check_no_diagnostic( 1024 //^^^^^^^^^^^^^^^^ Missing match arm
1372 r" 1025 Either::A(_) => (),
1373 enum Either { 1026 Either::B(false, _) => (),
1374 A(bool),
1375 B,
1376 }
1377 fn test_fn() {
1378 match Either::B {
1379 Either::A(_) => (),
1380 Either::B => (),
1381 }
1382 }
1383 ",
1384 );
1385 } 1027 }
1386 1028
1387 #[test] 1029 match Either::A(false) {
1388 fn enum_different_sizes_missing_arms() { 1030 Either::A(_) => (),
1389 check_diagnostic( 1031 Either::B(true, _) => (),
1390 r" 1032 Either::B(false, _) => (),
1391 enum Either {
1392 A(bool),
1393 B(bool, bool),
1394 }
1395 fn test_fn() {
1396 match Either::A(false) {
1397 Either::A(_) => (),
1398 Either::B(false, _) => (),
1399 }
1400 }
1401 ",
1402 );
1403 } 1033 }
1404 1034 match Either::A(false) {
1405 #[test] 1035 Either::A(true) | Either::A(false) => (),
1406 fn enum_different_sizes_no_diagnostic() { 1036 Either::B(true, _) => (),
1407 check_no_diagnostic( 1037 Either::B(false, _) => (),
1408 r"
1409 enum Either {
1410 A(bool),
1411 B(bool, bool),
1412 }
1413 fn test_fn() {
1414 match Either::A(false) {
1415 Either::A(_) => (),
1416 Either::B(true, _) => (),
1417 Either::B(false, _) => (),
1418 }
1419 }
1420 ",
1421 );
1422 } 1038 }
1423 1039}
1424 #[test] 1040"#,
1425 fn or_no_diagnostic() {
1426 check_no_diagnostic(
1427 r"
1428 enum Either {
1429 A(bool),
1430 B(bool, bool),
1431 }
1432 fn test_fn() {
1433 match Either::A(false) {
1434 Either::A(true) | Either::A(false) => (),
1435 Either::B(true, _) => (),
1436 Either::B(false, _) => (),
1437 }
1438 }
1439 ",
1440 ); 1041 );
1441 } 1042 }
1442 1043
1443 #[test] 1044 #[test]
1444 fn tuple_of_enum_no_diagnostic() { 1045 fn tuple_of_enum_no_diagnostic() {
1445 check_no_diagnostic( 1046 check_diagnostics(
1446 r" 1047 r#"
1447 enum Either { 1048enum Either { A(bool), B(bool, bool) }
1448 A(bool), 1049enum Either2 { C, D }
1449 B(bool, bool), 1050
1450 } 1051fn main() {
1451 enum Either2 { 1052 match (Either::A(false), Either2::C) {
1452 C, 1053 (Either::A(true), _) | (Either::A(false), _) => (),
1453 D, 1054 (Either::B(true, _), Either2::C) => (),
1454 } 1055 (Either::B(false, _), Either2::C) => (),
1455 fn test_fn() { 1056 (Either::B(_, _), Either2::D) => (),
1456 match (Either::A(false), Either2::C) {
1457 (Either::A(true), _) | (Either::A(false), _) => (),
1458 (Either::B(true, _), Either2::C) => (),
1459 (Either::B(false, _), Either2::C) => (),
1460 (Either::B(_, _), Either2::D) => (),
1461 }
1462 }
1463 ",
1464 );
1465 } 1057 }
1466 1058}
1467 #[test] 1059"#,
1468 fn mismatched_types() {
1469 // Match statements with arms that don't match the
1470 // expression pattern do not fire this diagnostic.
1471 check_no_diagnostic(
1472 r"
1473 enum Either {
1474 A,
1475 B,
1476 }
1477 enum Either2 {
1478 C,
1479 D,
1480 }
1481 fn test_fn() {
1482 match Either::A {
1483 Either2::C => (),
1484 Either2::D => (),
1485 }
1486 }
1487 ",
1488 );
1489 }
1490
1491 #[test]
1492 fn mismatched_types_with_different_arity() {
1493 // Match statements with arms that don't match the
1494 // expression pattern do not fire this diagnostic.
1495 check_no_diagnostic(
1496 r"
1497 fn test_fn() {
1498 match (true, false) {
1499 (true, false, true) => (),
1500 (true) => (),
1501 }
1502 }
1503 ",
1504 ); 1060 );
1505 } 1061 }
1506 1062
1507 #[test] 1063 #[test]
1508 fn malformed_match_arm_tuple_missing_pattern() { 1064 fn mismatched_types() {
1509 // Match statements with arms that don't match the 1065 // Match statements with arms that don't match the
1510 // expression pattern do not fire this diagnostic. 1066 // expression pattern do not fire this diagnostic.
1511 check_no_diagnostic( 1067 check_diagnostics(
1512 r" 1068 r#"
1513 fn test_fn() { 1069enum Either { A, B }
1514 match (0) { 1070enum Either2 { C, D }
1515 () => (), 1071
1516 } 1072fn main() {
1517 } 1073 match Either::A {
1518 ", 1074 Either2::C => (),
1075 Either2::D => (),
1076 }
1077 match (true, false) {
1078 (true, false, true) => (),
1079 (true) => (),
1080 }
1081 match (0) { () => () }
1082 match Unresolved::Bar { Unresolved::Baz => () }
1083}
1084 "#,
1519 ); 1085 );
1520 } 1086 }
1521 1087
@@ -1523,517 +1089,247 @@ mod tests {
1523 fn malformed_match_arm_tuple_enum_missing_pattern() { 1089 fn malformed_match_arm_tuple_enum_missing_pattern() {
1524 // We are testing to be sure we don't panic here when the match 1090 // We are testing to be sure we don't panic here when the match
1525 // arm `Either::B` is missing its pattern. 1091 // arm `Either::B` is missing its pattern.
1526 check_no_diagnostic( 1092 check_diagnostics(
1527 r" 1093 r#"
1528 enum Either { 1094enum Either { A, B(u32) }
1529 A,
1530 B(u32),
1531 }
1532 fn test_fn() {
1533 match Either::A {
1534 Either::A => (),
1535 Either::B() => (),
1536 }
1537 }
1538 ",
1539 );
1540 }
1541 1095
1542 #[test] 1096fn main() {
1543 fn enum_not_in_scope() { 1097 match Either::A {
1544 // The enum is not in scope so we don't perform exhaustiveness 1098 Either::A => (),
1545 // checking, but we want to be sure we don't panic here (and 1099 Either::B() => (),
1546 // we don't create a diagnostic). 1100 }
1547 check_no_diagnostic( 1101}
1548 r" 1102"#,
1549 fn test_fn() {
1550 match Foo::Bar {
1551 Foo::Baz => (),
1552 }
1553 }
1554 ",
1555 ); 1103 );
1556 } 1104 }
1557 1105
1558 #[test] 1106 #[test]
1559 fn expr_diverges() { 1107 fn expr_diverges() {
1560 check_no_diagnostic( 1108 check_diagnostics(
1561 r" 1109 r#"
1562 enum Either { 1110enum Either { A, B }
1563 A,
1564 B,
1565 }
1566 fn test_fn() {
1567 match loop {} {
1568 Either::A => (),
1569 Either::B => (),
1570 }
1571 }
1572 ",
1573 );
1574 }
1575 1111
1576 #[test] 1112fn main() {
1577 fn expr_loop_with_break() { 1113 match loop {} {
1578 check_no_diagnostic( 1114 Either::A => (),
1579 r" 1115 Either::B => (),
1580 enum Either { 1116 }
1581 A, 1117 match loop {} {
1582 B, 1118 Either::A => (),
1583 } 1119 }
1584 fn test_fn() { 1120 match loop { break Foo::A } {
1585 match loop { break Foo::A } { 1121 //^^^^^^^^^^^^^^^^^^^^^ Missing match arm
1586 Either::A => (), 1122 Either::A => (),
1587 Either::B => (), 1123 }
1588 } 1124 match loop { break Foo::A } {
1589 } 1125 Either::A => (),
1590 ", 1126 Either::B => (),
1127 }
1128}
1129"#,
1591 ); 1130 );
1592 } 1131 }
1593 1132
1594 #[test] 1133 #[test]
1595 fn expr_partially_diverges() { 1134 fn expr_partially_diverges() {
1596 check_no_diagnostic( 1135 check_diagnostics(
1597 r" 1136 r#"
1598 enum Either<T> { 1137enum Either<T> { A(T), B }
1599 A(T),
1600 B,
1601 }
1602 fn foo() -> Either<!> {
1603 Either::B
1604 }
1605 fn test_fn() -> u32 {
1606 match foo() {
1607 Either::A(val) => val,
1608 Either::B => 0,
1609 }
1610 }
1611 ",
1612 );
1613 }
1614 1138
1615 #[test] 1139fn foo() -> Either<!> { Either::B }
1616 fn enum_record_no_arms() { 1140fn main() -> u32 {
1617 check_diagnostic( 1141 match foo() {
1618 r" 1142 Either::A(val) => val,
1619 enum Either { 1143 Either::B => 0,
1620 A { foo: bool },
1621 B,
1622 }
1623 fn test_fn() {
1624 let a = Either::A { foo: true };
1625 match a {
1626 }
1627 }
1628 ",
1629 );
1630 } 1144 }
1631 1145}
1632 #[test] 1146"#,
1633 fn enum_record_missing_arms() {
1634 check_diagnostic(
1635 r"
1636 enum Either {
1637 A { foo: bool },
1638 B,
1639 }
1640 fn test_fn() {
1641 let a = Either::A { foo: true };
1642 match a {
1643 Either::A { foo: true } => (),
1644 }
1645 }
1646 ",
1647 ); 1147 );
1648 } 1148 }
1649 1149
1650 #[test] 1150 #[test]
1651 fn enum_record_no_diagnostic() { 1151 fn enum_record() {
1652 check_no_diagnostic( 1152 check_diagnostics(
1653 r" 1153 r#"
1654 enum Either { 1154enum Either { A { foo: bool }, B }
1655 A { foo: bool },
1656 B,
1657 }
1658 fn test_fn() {
1659 let a = Either::A { foo: true };
1660 match a {
1661 Either::A { foo: true } => (),
1662 Either::A { foo: false } => (),
1663 Either::B => (),
1664 }
1665 }
1666 ",
1667 );
1668 }
1669 1155
1670 #[test] 1156fn main() {
1671 fn enum_record_missing_field_no_diagnostic() { 1157 let a = Either::A { foo: true };
1672 // When `Either::A` is missing a struct member, we don't want 1158 match a { }
1673 // to fire the missing match arm diagnostic. This should fire 1159 //^ Missing match arm
1674 // some other diagnostic. 1160 match a { Either::A { foo: true } => () }
1675 check_no_diagnostic( 1161 //^ Missing match arm
1676 r" 1162 match a {
1677 enum Either { 1163 Either::A { } => (),
1678 A { foo: bool }, 1164 //^^^ Missing structure fields:
1679 B, 1165 Either::B => (),
1680 }
1681 fn test_fn() {
1682 let a = Either::B;
1683 match a {
1684 Either::A { } => (),
1685 Either::B => (),
1686 }
1687 }
1688 ",
1689 );
1690 } 1166 }
1167 match a {
1168 //^ Missing match arm
1169 Either::A { } => (),
1170 } //^^^ Missing structure fields:
1691 1171
1692 #[test] 1172 match a {
1693 fn enum_record_missing_field_missing_match_arm() { 1173 Either::A { foo: true } => (),
1694 // Even though `Either::A` is missing fields, we still want to fire 1174 Either::A { foo: false } => (),
1695 // the missing arm diagnostic here, since we know `Either::B` is missing. 1175 Either::B => (),
1696 check_diagnostic(
1697 r"
1698 enum Either {
1699 A { foo: bool },
1700 B,
1701 }
1702 fn test_fn() {
1703 let a = Either::B;
1704 match a {
1705 Either::A { } => (),
1706 }
1707 }
1708 ",
1709 );
1710 } 1176 }
1711 1177 match a {
1712 #[test] 1178 Either::A { foo: _ } => (),
1713 fn enum_record_no_diagnostic_wild() { 1179 Either::B => (),
1714 check_no_diagnostic(
1715 r"
1716 enum Either {
1717 A { foo: bool },
1718 B,
1719 }
1720 fn test_fn() {
1721 let a = Either::A { foo: true };
1722 match a {
1723 Either::A { foo: _ } => (),
1724 Either::B => (),
1725 }
1726 }
1727 ",
1728 );
1729 } 1180 }
1730 1181}
1731 #[test] 1182"#,
1732 fn enum_record_fields_out_of_order_missing_arm() {
1733 check_diagnostic(
1734 r"
1735 enum Either {
1736 A { foo: bool, bar: () },
1737 B,
1738 }
1739 fn test_fn() {
1740 let a = Either::A { foo: true };
1741 match a {
1742 Either::A { bar: (), foo: false } => (),
1743 Either::A { foo: true, bar: () } => (),
1744 }
1745 }
1746 ",
1747 ); 1183 );
1748 } 1184 }
1749 1185
1750 #[test] 1186 #[test]
1751 fn enum_record_fields_out_of_order_no_diagnostic() { 1187 fn enum_record_fields_out_of_order() {
1752 check_no_diagnostic( 1188 check_diagnostics(
1753 r" 1189 r#"
1754 enum Either { 1190enum Either {
1755 A { foo: bool, bar: () }, 1191 A { foo: bool, bar: () },
1756 B, 1192 B,
1757 } 1193}
1758 fn test_fn() {
1759 let a = Either::A { foo: true };
1760 match a {
1761 Either::A { bar: (), foo: false } => (),
1762 Either::A { foo: true, bar: () } => (),
1763 Either::B => (),
1764 }
1765 }
1766 ",
1767 );
1768 }
1769 1194
1770 #[test] 1195fn main() {
1771 fn enum_record_ellipsis_missing_arm() { 1196 let a = Either::A { foo: true, bar: () };
1772 check_diagnostic( 1197 match a {
1773 r" 1198 //^ Missing match arm
1774 enum Either { 1199 Either::A { bar: (), foo: false } => (),
1775 A { foo: bool, bar: bool }, 1200 Either::A { foo: true, bar: () } => (),
1776 B,
1777 }
1778 fn test_fn() {
1779 match Either::B {
1780 Either::A { foo: true, .. } => (),
1781 Either::B => (),
1782 }
1783 }
1784 ",
1785 );
1786 } 1201 }
1787 1202
1788 #[test] 1203 match a {
1789 fn enum_record_ellipsis_no_diagnostic() { 1204 Either::A { bar: (), foo: false } => (),
1790 check_no_diagnostic( 1205 Either::A { foo: true, bar: () } => (),
1791 r" 1206 Either::B => (),
1792 enum Either {
1793 A { foo: bool, bar: bool },
1794 B,
1795 }
1796 fn test_fn() {
1797 let a = Either::A { foo: true };
1798 match a {
1799 Either::A { foo: true, .. } => (),
1800 Either::A { foo: false, .. } => (),
1801 Either::B => (),
1802 }
1803 }
1804 ",
1805 );
1806 } 1207 }
1807 1208}
1808 #[test] 1209"#,
1809 fn enum_record_ellipsis_all_fields_missing_arm() {
1810 check_diagnostic(
1811 r"
1812 enum Either {
1813 A { foo: bool, bar: bool },
1814 B,
1815 }
1816 fn test_fn() {
1817 let a = Either::B;
1818 match a {
1819 Either::A { .. } => (),
1820 }
1821 }
1822 ",
1823 ); 1210 );
1824 } 1211 }
1825 1212
1826 #[test] 1213 #[test]
1827 fn enum_record_ellipsis_all_fields_no_diagnostic() { 1214 fn enum_record_ellipsis() {
1828 check_no_diagnostic( 1215 check_diagnostics(
1829 r" 1216 r#"
1830 enum Either { 1217enum Either {
1831 A { foo: bool, bar: bool }, 1218 A { foo: bool, bar: bool },
1832 B, 1219 B,
1833 } 1220}
1834 fn test_fn() {
1835 let a = Either::B;
1836 match a {
1837 Either::A { .. } => (),
1838 Either::B => (),
1839 }
1840 }
1841 ",
1842 );
1843 }
1844 1221
1845 #[test] 1222fn main() {
1846 fn enum_tuple_partial_ellipsis_no_diagnostic() { 1223 let a = Either::B;
1847 check_no_diagnostic( 1224 match a {
1848 r" 1225 //^ Missing match arm
1849 enum Either { 1226 Either::A { foo: true, .. } => (),
1850 A(bool, bool, bool, bool), 1227 Either::B => (),
1851 B,
1852 }
1853 fn test_fn() {
1854 match Either::B {
1855 Either::A(true, .., true) => {},
1856 Either::A(true, .., false) => {},
1857 Either::A(false, .., true) => {},
1858 Either::A(false, .., false) => {},
1859 Either::B => {},
1860 }
1861 }
1862 ",
1863 );
1864 } 1228 }
1865 1229 match a {
1866 #[test] 1230 //^ Missing match arm
1867 fn enum_tuple_partial_ellipsis_2_no_diagnostic() { 1231 Either::A { .. } => (),
1868 check_no_diagnostic(
1869 r"
1870 enum Either {
1871 A(bool, bool, bool, bool),
1872 B,
1873 }
1874 fn test_fn() {
1875 match Either::B {
1876 Either::A(true, .., true) => {},
1877 Either::A(true, .., false) => {},
1878 Either::A(.., true) => {},
1879 Either::A(.., false) => {},
1880 Either::B => {},
1881 }
1882 }
1883 ",
1884 );
1885 } 1232 }
1886 1233
1887 #[test] 1234 match a {
1888 fn enum_tuple_partial_ellipsis_missing_arm() { 1235 Either::A { foo: true, .. } => (),
1889 check_diagnostic( 1236 Either::A { foo: false, .. } => (),
1890 r" 1237 Either::B => (),
1891 enum Either {
1892 A(bool, bool, bool, bool),
1893 B,
1894 }
1895 fn test_fn() {
1896 match Either::B {
1897 Either::A(true, .., true) => {},
1898 Either::A(true, .., false) => {},
1899 Either::A(false, .., false) => {},
1900 Either::B => {},
1901 }
1902 }
1903 ",
1904 );
1905 } 1238 }
1906 1239
1907 #[test] 1240 match a {
1908 fn enum_tuple_partial_ellipsis_2_missing_arm() { 1241 Either::A { .. } => (),
1909 check_diagnostic( 1242 Either::B => (),
1910 r"
1911 enum Either {
1912 A(bool, bool, bool, bool),
1913 B,
1914 }
1915 fn test_fn() {
1916 match Either::B {
1917 Either::A(true, .., true) => {},
1918 Either::A(true, .., false) => {},
1919 Either::A(.., true) => {},
1920 Either::B => {},
1921 }
1922 }
1923 ",
1924 );
1925 } 1243 }
1926 1244}
1927 #[test] 1245"#,
1928 fn enum_tuple_ellipsis_no_diagnostic() {
1929 check_no_diagnostic(
1930 r"
1931 enum Either {
1932 A(bool, bool, bool, bool),
1933 B,
1934 }
1935 fn test_fn() {
1936 match Either::B {
1937 Either::A(..) => {},
1938 Either::B => {},
1939 }
1940 }
1941 ",
1942 ); 1246 );
1943 } 1247 }
1944 1248
1945 #[test] 1249 #[test]
1946 fn enum_never() { 1250 fn enum_tuple_partial_ellipsis() {
1947 check_no_diagnostic( 1251 check_diagnostics(
1948 r" 1252 r#"
1949 enum Never {} 1253enum Either {
1254 A(bool, bool, bool, bool),
1255 B,
1256}
1950 1257
1951 fn test_fn(never: Never) { 1258fn main() {
1952 match never {} 1259 match Either::B {
1953 } 1260 //^^^^^^^^^ Missing match arm
1954 ", 1261 Either::A(true, .., true) => (),
1955 ); 1262 Either::A(true, .., false) => (),
1263 Either::A(false, .., false) => (),
1264 Either::B => (),
1265 }
1266 match Either::B {
1267 //^^^^^^^^^ Missing match arm
1268 Either::A(true, .., true) => (),
1269 Either::A(true, .., false) => (),
1270 Either::A(.., true) => (),
1271 Either::B => (),
1272 }
1273
1274 match Either::B {
1275 Either::A(true, .., true) => (),
1276 Either::A(true, .., false) => (),
1277 Either::A(false, .., true) => (),
1278 Either::A(false, .., false) => (),
1279 Either::B => (),
1280 }
1281 match Either::B {
1282 Either::A(true, .., true) => (),
1283 Either::A(true, .., false) => (),
1284 Either::A(.., true) => (),
1285 Either::A(.., false) => (),
1286 Either::B => (),
1956 } 1287 }
1957 1288}
1958 #[test] 1289"#,
1959 fn type_never() {
1960 check_no_diagnostic(
1961 r"
1962 fn test_fn(never: !) {
1963 match never {}
1964 }
1965 ",
1966 ); 1290 );
1967 } 1291 }
1968 1292
1969 #[test] 1293 #[test]
1970 fn enum_never_ref() { 1294 fn never() {
1971 check_no_diagnostic( 1295 check_diagnostics(
1972 r" 1296 r#"
1973 enum Never {} 1297enum Never {}
1974 1298
1975 fn test_fn(never: &Never) { 1299fn enum_(never: Never) {
1976 match never {} 1300 match never {}
1977 } 1301}
1978 ", 1302fn enum_ref(never: &Never) {
1979 ); 1303 match never {}
1980 } 1304}
1981 1305fn bang(never: !) {
1982 #[test] 1306 match never {}
1983 fn expr_diverges_missing_arm() { 1307}
1984 check_no_diagnostic( 1308"#,
1985 r"
1986 enum Either {
1987 A,
1988 B,
1989 }
1990 fn test_fn() {
1991 match loop {} {
1992 Either::A => (),
1993 }
1994 }
1995 ",
1996 ); 1309 );
1997 } 1310 }
1998 1311
1999 #[test] 1312 #[test]
2000 fn or_pattern_panic() { 1313 fn or_pattern_panic() {
2001 check_no_diagnostic( 1314 check_diagnostics(
2002 r" 1315 r#"
2003 pub enum Category { 1316pub enum Category { Infinity, Zero }
2004 Infinity,
2005 Zero,
2006 }
2007 1317
2008 fn panic(a: Category, b: Category) { 1318fn panic(a: Category, b: Category) {
2009 match (a, b) { 1319 match (a, b) {
2010 (Category::Zero | Category::Infinity, _) => {} 1320 (Category::Zero | Category::Infinity, _) => (),
2011 (_, Category::Zero | Category::Infinity) => {} 1321 (_, Category::Zero | Category::Infinity) => (),
2012 }
2013 }
2014 ",
2015 );
2016 } 1322 }
2017 1323
2018 #[test] 1324 // FIXME: This is a false positive, but the code used to cause a panic in the match checker,
2019 fn or_pattern_panic_2() { 1325 // so this acts as a regression test for that.
2020 // FIXME: This is a false positive, but the code used to cause a panic in the match checker, 1326 match (a, b) {
2021 // so this acts as a regression test for that. 1327 //^^^^^^ Missing match arm
2022 check_diagnostic( 1328 (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => (),
2023 r" 1329 (Category::Infinity | Category::Zero, _) => (),
2024 pub enum Category { 1330 }
2025 Infinity, 1331}
2026 Zero, 1332"#,
2027 }
2028
2029 fn panic(a: Category, b: Category) {
2030 match (a, b) {
2031 (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => {}
2032
2033 (Category::Infinity | Category::Zero, _) => {}
2034 }
2035 }
2036 ",
2037 ); 1333 );
2038 } 1334 }
2039 1335
@@ -2051,105 +1347,72 @@ mod tests {
2051 1347
2052 #[test] 1348 #[test]
2053 fn integers() { 1349 fn integers() {
2054 // This is a false negative.
2055 // We don't currently check integer exhaustiveness. 1350 // We don't currently check integer exhaustiveness.
2056 check_no_diagnostic( 1351 check_diagnostics(
2057 r" 1352 r#"
2058 fn test_fn() { 1353fn main() {
2059 match 5 { 1354 match 5 {
2060 10 => (), 1355 10 => (),
2061 11..20 => (), 1356 11..20 => (),
2062 } 1357 }
2063 } 1358}
2064 ", 1359"#,
2065 ); 1360 );
2066 } 1361 }
2067 1362
2068 #[test] 1363 #[test]
2069 fn internal_or() { 1364 fn internal_or() {
2070 // This is a false negative.
2071 // We do not currently handle patterns with internal `or`s. 1365 // We do not currently handle patterns with internal `or`s.
2072 check_no_diagnostic( 1366 check_diagnostics(
2073 r" 1367 r#"
2074 fn test_fn() { 1368fn main() {
2075 enum Either { 1369 enum Either { A(bool), B }
2076 A(bool), 1370 match Either::B {
2077 B, 1371 Either::A(true | false) => (),
2078 } 1372 }
2079 match Either::B { 1373}
2080 Either::A(true | false) => (), 1374"#,
2081 }
2082 }
2083 ",
2084 );
2085 }
2086
2087 #[test]
2088 fn expr_loop_missing_arm() {
2089 // This is a false negative.
2090 // We currently infer the type of `loop { break Foo::A }` to `!`, which
2091 // causes us to skip the diagnostic since `Either::A` doesn't type check
2092 // with `!`.
2093 check_diagnostic(
2094 r"
2095 enum Either {
2096 A,
2097 B,
2098 }
2099 fn test_fn() {
2100 match loop { break Foo::A } {
2101 Either::A => (),
2102 }
2103 }
2104 ",
2105 ); 1375 );
2106 } 1376 }
2107 1377
2108 #[test] 1378 #[test]
2109 fn tuple_of_bools_with_ellipsis_at_end_missing_arm() { 1379 fn tuple_of_bools_with_ellipsis_at_end_missing_arm() {
2110 // This is a false negative.
2111 // We don't currently handle tuple patterns with ellipsis. 1380 // We don't currently handle tuple patterns with ellipsis.
2112 check_no_diagnostic( 1381 check_diagnostics(
2113 r" 1382 r#"
2114 fn test_fn() { 1383fn main() {
2115 match (false, true, false) { 1384 match (false, true, false) {
2116 (false, ..) => {}, 1385 (false, ..) => (),
2117 } 1386 }
2118 } 1387}
2119 ", 1388"#,
2120 ); 1389 );
2121 } 1390 }
2122 1391
2123 #[test] 1392 #[test]
2124 fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() { 1393 fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() {
2125 // This is a false negative.
2126 // We don't currently handle tuple patterns with ellipsis. 1394 // We don't currently handle tuple patterns with ellipsis.
2127 check_no_diagnostic( 1395 check_diagnostics(
2128 r" 1396 r#"
2129 fn test_fn() { 1397fn main() {
2130 match (false, true, false) { 1398 match (false, true, false) {
2131 (.., false) => {}, 1399 (.., false) => (),
2132 } 1400 }
2133 } 1401}
2134 ", 1402"#,
2135 ); 1403 );
2136 } 1404 }
2137 1405
2138 #[test] 1406 #[test]
2139 fn struct_missing_arm() { 1407 fn struct_missing_arm() {
2140 // This is a false negative.
2141 // We don't currently handle structs. 1408 // We don't currently handle structs.
2142 check_no_diagnostic( 1409 check_diagnostics(
2143 r" 1410 r#"
2144 struct Foo { 1411struct Foo { a: bool }
2145 a: bool, 1412fn main(f: Foo) {
2146 } 1413 match f { Foo { a: true } => () }
2147 fn test_fn(f: Foo) { 1414}
2148 match f { 1415"#,
2149 Foo { a: true } => {},
2150 }
2151 }
2152 ",
2153 ); 1416 );
2154 } 1417 }
2155 } 1418 }
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index ddafd0ea1..fb8723fb7 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -82,7 +82,7 @@ impl FileLoader for TestDB {
82} 82}
83 83
84impl TestDB { 84impl TestDB {
85 pub fn module_for_file(&self, file_id: FileId) -> ModuleId { 85 pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
86 for &krate in self.relevant_crates(file_id).iter() { 86 for &krate in self.relevant_crates(file_id).iter() {
87 let crate_def_map = self.crate_def_map(krate); 87 let crate_def_map = self.crate_def_map(krate);
88 for (local_id, data) in crate_def_map.modules.iter() { 88 for (local_id, data) in crate_def_map.modules.iter() {
@@ -94,7 +94,7 @@ impl TestDB {
94 panic!("Can't find module for file") 94 panic!("Can't find module for file")
95 } 95 }
96 96
97 fn diag<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) { 97 pub(crate) fn diag<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) {
98 let crate_graph = self.crate_graph(); 98 let crate_graph = self.crate_graph();
99 for krate in crate_graph.iter() { 99 for krate in crate_graph.iter() {
100 let crate_def_map = self.crate_def_map(krate); 100 let crate_def_map = self.crate_def_map(krate);
@@ -124,7 +124,7 @@ impl TestDB {
124 } 124 }
125 } 125 }
126 126
127 pub fn diagnostics(&self) -> (String, u32) { 127 pub(crate) fn diagnostics(&self) -> (String, u32) {
128 let mut buf = String::new(); 128 let mut buf = String::new();
129 let mut count = 0; 129 let mut count = 0;
130 self.diag(|d| { 130 self.diag(|d| {
@@ -134,22 +134,7 @@ impl TestDB {
134 (buf, count) 134 (buf, count)
135 } 135 }
136 136
137 /// Like `diagnostics`, but filtered for a single diagnostic. 137 pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
138 pub fn diagnostic<D: Diagnostic>(&self) -> (String, u32) {
139 let mut buf = String::new();
140 let mut count = 0;
141 self.diag(|d| {
142 // We want to filter diagnostics by the particular one we are testing for, to
143 // avoid surprising results in tests.
144 if d.downcast_ref::<D>().is_some() {
145 format_to!(buf, "{:?}: {}\n", d.syntax_node(self).text(), d.message());
146 count += 1;
147 };
148 });
149 (buf, count)
150 }
151
152 pub fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
153 let mut files = Vec::new(); 138 let mut files = Vec::new();
154 let crate_graph = self.crate_graph(); 139 let crate_graph = self.crate_graph();
155 for krate in crate_graph.iter() { 140 for krate in crate_graph.iter() {