@@ -972,6 +972,47 @@ mod tests {
972972 check_no_diagnostic ( content) ;
973973 }
974974
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+
9751016 #[ test]
9761017 fn tuple_of_tuple_and_bools_no_arms ( ) {
9771018 let content = r"
@@ -1315,8 +1356,9 @@ mod tests {
13151356 }
13161357 " ;
13171358
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) ;
13201362 }
13211363
13221364 #[ test]
@@ -1330,8 +1372,9 @@ mod tests {
13301372 }
13311373 " ;
13321374
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) ;
13351378 }
13361379
13371380 #[ test]
@@ -1344,8 +1387,9 @@ mod tests {
13441387 }
13451388 " ;
13461389
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) ;
13491393 }
13501394
13511395 #[ test]
@@ -1383,6 +1427,102 @@ mod tests {
13831427 // we don't create a diagnostic).
13841428 check_no_diagnostic ( content) ;
13851429 }
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+ }
13861526}
13871527
13881528#[ cfg( test) ]
@@ -1452,4 +1592,104 @@ mod false_negatives {
14521592 // We do not currently handle patterns with internal `or`s.
14531593 check_no_diagnostic ( content) ;
14541594 }
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+ }
14551695}
0 commit comments