@@ -972,6 +972,47 @@ mod tests {
972
972
check_no_diagnostic ( content) ;
973
973
}
974
974
975
+ #[ test]
976
+ fn tuple_of_bools_with_ellipsis_at_end_no_diagnostic ( ) {
977
+ let content = r"
978
+ fn test_fn() {
979
+ match (false, true, false) {
980
+ (false, ..) => {},
981
+ (true, ..) => {},
982
+ }
983
+ }
984
+ " ;
985
+
986
+ check_no_diagnostic ( content) ;
987
+ }
988
+
989
+ #[ test]
990
+ fn tuple_of_bools_with_ellipsis_at_beginning_no_diagnostic ( ) {
991
+ let content = r"
992
+ fn test_fn() {
993
+ match (false, true, false) {
994
+ (.., false) => {},
995
+ (.., true) => {},
996
+ }
997
+ }
998
+ " ;
999
+
1000
+ check_no_diagnostic ( content) ;
1001
+ }
1002
+
1003
+ #[ test]
1004
+ fn tuple_of_bools_with_ellipsis_no_diagnostic ( ) {
1005
+ let content = r"
1006
+ fn test_fn() {
1007
+ match (false, true, false) {
1008
+ (..) => {},
1009
+ }
1010
+ }
1011
+ " ;
1012
+
1013
+ check_no_diagnostic ( content) ;
1014
+ }
1015
+
975
1016
#[ test]
976
1017
fn tuple_of_tuple_and_bools_no_arms ( ) {
977
1018
let content = r"
@@ -1315,8 +1356,9 @@ mod tests {
1315
1356
}
1316
1357
" ;
1317
1358
1318
- // Match arms with the incorrect type are filtered out.
1319
- check_diagnostic ( content) ;
1359
+ // Match statements with arms that don't match the
1360
+ // expression pattern do not fire this diagnostic.
1361
+ check_no_diagnostic ( content) ;
1320
1362
}
1321
1363
1322
1364
#[ test]
@@ -1330,8 +1372,9 @@ mod tests {
1330
1372
}
1331
1373
" ;
1332
1374
1333
- // Match arms with the incorrect type are filtered out.
1334
- check_diagnostic ( content) ;
1375
+ // Match statements with arms that don't match the
1376
+ // expression pattern do not fire this diagnostic.
1377
+ check_no_diagnostic ( content) ;
1335
1378
}
1336
1379
1337
1380
#[ test]
@@ -1344,8 +1387,9 @@ mod tests {
1344
1387
}
1345
1388
" ;
1346
1389
1347
- // Match arms with the incorrect type are filtered out.
1348
- check_diagnostic ( content) ;
1390
+ // Match statements with arms that don't match the
1391
+ // expression pattern do not fire this diagnostic.
1392
+ check_no_diagnostic ( content) ;
1349
1393
}
1350
1394
1351
1395
#[ test]
@@ -1383,6 +1427,102 @@ mod tests {
1383
1427
// we don't create a diagnostic).
1384
1428
check_no_diagnostic ( content) ;
1385
1429
}
1430
+
1431
+ #[ test]
1432
+ fn expr_diverges ( ) {
1433
+ let content = r"
1434
+ enum Either {
1435
+ A,
1436
+ B,
1437
+ }
1438
+ fn test_fn() {
1439
+ match loop {} {
1440
+ Either::A => (),
1441
+ Either::B => (),
1442
+ }
1443
+ }
1444
+ " ;
1445
+
1446
+ check_no_diagnostic ( content) ;
1447
+ }
1448
+
1449
+ #[ test]
1450
+ fn expr_loop_with_break ( ) {
1451
+ let content = r"
1452
+ enum Either {
1453
+ A,
1454
+ B,
1455
+ }
1456
+ fn test_fn() {
1457
+ match loop { break Foo::A } {
1458
+ Either::A => (),
1459
+ Either::B => (),
1460
+ }
1461
+ }
1462
+ " ;
1463
+
1464
+ check_no_diagnostic ( content) ;
1465
+ }
1466
+
1467
+ #[ test]
1468
+ fn expr_partially_diverges ( ) {
1469
+ let content = r"
1470
+ enum Either<T> {
1471
+ A(T),
1472
+ B,
1473
+ }
1474
+ fn foo() -> Either<!> {
1475
+ Either::B
1476
+ }
1477
+ fn test_fn() -> u32 {
1478
+ match foo() {
1479
+ Either::A(val) => val,
1480
+ Either::B => 0,
1481
+ }
1482
+ }
1483
+ " ;
1484
+
1485
+ check_no_diagnostic ( content) ;
1486
+ }
1487
+
1488
+ #[ test]
1489
+ fn enum_tuple_partial_ellipsis_no_diagnostic ( ) {
1490
+ let content = r"
1491
+ enum Either {
1492
+ A(bool, bool, bool, bool),
1493
+ B,
1494
+ }
1495
+ fn test_fn() {
1496
+ match Either::B {
1497
+ Either::A(true, .., true) => {},
1498
+ Either::A(true, .., false) => {},
1499
+ Either::A(false, .., true) => {},
1500
+ Either::A(false, .., false) => {},
1501
+ Either::B => {},
1502
+ }
1503
+ }
1504
+ " ;
1505
+
1506
+ check_no_diagnostic ( content) ;
1507
+ }
1508
+
1509
+ #[ test]
1510
+ fn enum_tuple_ellipsis_no_diagnostic ( ) {
1511
+ let content = r"
1512
+ enum Either {
1513
+ A(bool, bool, bool, bool),
1514
+ B,
1515
+ }
1516
+ fn test_fn() {
1517
+ match Either::B {
1518
+ Either::A(..) => {},
1519
+ Either::B => {},
1520
+ }
1521
+ }
1522
+ " ;
1523
+
1524
+ check_no_diagnostic ( content) ;
1525
+ }
1386
1526
}
1387
1527
1388
1528
#[ cfg( test) ]
@@ -1452,4 +1592,104 @@ mod false_negatives {
1452
1592
// We do not currently handle patterns with internal `or`s.
1453
1593
check_no_diagnostic ( content) ;
1454
1594
}
1595
+
1596
+ #[ test]
1597
+ fn expr_diverges_missing_arm ( ) {
1598
+ let content = r"
1599
+ enum Either {
1600
+ A,
1601
+ B,
1602
+ }
1603
+ fn test_fn() {
1604
+ match loop {} {
1605
+ Either::A => (),
1606
+ }
1607
+ }
1608
+ " ;
1609
+
1610
+ // This is a false negative.
1611
+ // Even though the match expression diverges, rustc fails
1612
+ // to compile here since `Either::B` is missing.
1613
+ check_no_diagnostic ( content) ;
1614
+ }
1615
+
1616
+ #[ test]
1617
+ fn expr_loop_missing_arm ( ) {
1618
+ let content = r"
1619
+ enum Either {
1620
+ A,
1621
+ B,
1622
+ }
1623
+ fn test_fn() {
1624
+ match loop { break Foo::A } {
1625
+ Either::A => (),
1626
+ }
1627
+ }
1628
+ " ;
1629
+
1630
+ // This is a false negative.
1631
+ // We currently infer the type of `loop { break Foo::A }` to `!`, which
1632
+ // causes us to skip the diagnostic since `Either::A` doesn't type check
1633
+ // with `!`.
1634
+ check_no_diagnostic ( content) ;
1635
+ }
1636
+
1637
+ #[ test]
1638
+ fn tuple_of_bools_with_ellipsis_at_end_missing_arm ( ) {
1639
+ let content = r"
1640
+ fn test_fn() {
1641
+ match (false, true, false) {
1642
+ (false, ..) => {},
1643
+ }
1644
+ }
1645
+ " ;
1646
+
1647
+ // This is a false negative.
1648
+ // The `..` pattern is currently lowered to a single `Pat::Wild`
1649
+ // no matter how many fields the `..` pattern is covering. This
1650
+ // causes the match arm in this test not to type check against
1651
+ // the match expression, which causes this diagnostic not to
1652
+ // fire.
1653
+ check_no_diagnostic ( content) ;
1654
+ }
1655
+
1656
+ #[ test]
1657
+ fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm ( ) {
1658
+ let content = r"
1659
+ fn test_fn() {
1660
+ match (false, true, false) {
1661
+ (.., false) => {},
1662
+ }
1663
+ }
1664
+ " ;
1665
+
1666
+ // This is a false negative.
1667
+ // See comments on `tuple_of_bools_with_ellipsis_at_end_missing_arm`.
1668
+ check_no_diagnostic ( content) ;
1669
+ }
1670
+
1671
+ #[ test]
1672
+ fn enum_tuple_partial_ellipsis_missing_arm ( ) {
1673
+ let content = r"
1674
+ enum Either {
1675
+ A(bool, bool, bool, bool),
1676
+ B,
1677
+ }
1678
+ fn test_fn() {
1679
+ match Either::B {
1680
+ Either::A(true, .., true) => {},
1681
+ Either::A(true, .., false) => {},
1682
+ Either::A(false, .., false) => {},
1683
+ Either::B => {},
1684
+ }
1685
+ }
1686
+ " ;
1687
+
1688
+ // This is a false negative.
1689
+ // The `..` pattern is currently lowered to a single `Pat::Wild`
1690
+ // no matter how many fields the `..` pattern is covering. This
1691
+ // causes us to return a `MatchCheckErr::MalformedMatchArm` in
1692
+ // `Pat::specialize_constructor`.
1693
+ check_no_diagnostic ( content) ;
1694
+ }
1455
1695
}
0 commit comments