|
548 | 548 | //! [`ValidityConstraint::specialize`].
|
549 | 549 | //!
|
550 | 550 | //! Having said all that, in practice we don't fully follow what's been presented in this section.
|
551 |
| -//! Under `exhaustive_patterns`, we allow omitting empty arms even in `!known_valid` places, for |
552 |
| -//! backwards-compatibility until we have a better alternative. Without `exhaustive_patterns`, we |
553 |
| -//! mostly treat empty types as inhabited, except specifically a non-nested `!` or empty enum. In |
554 |
| -//! this specific case we also allow the empty match regardless of place validity, for |
555 |
| -//! backwards-compatibility. Hopefully we can eventually deprecate this. |
| 551 | +//! Let's call "toplevel exception" the case where the match scrutinee itself has type `!` or |
| 552 | +//! `EmptyEnum`. First, on stable rust, we require `_` patterns for empty types in all cases apart |
| 553 | +//! from the toplevel exception. The `exhaustive_patterns` and `min_exaustive_patterns` allow |
| 554 | +//! omitting patterns in the cases described above. There's a final detail: in the toplevel |
| 555 | +//! exception or with the `exhaustive_patterns` feature, we ignore place validity when checking |
| 556 | +//! whether a pattern is required for exhaustiveness. I (Nadrieril) hope to deprecate this behavior. |
556 | 557 | //!
|
557 | 558 | //!
|
558 | 559 | //!
|
@@ -1442,10 +1443,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
|
1442 | 1443 | // We treat match scrutinees of type `!` or `EmptyEnum` differently.
|
1443 | 1444 | let is_toplevel_exception =
|
1444 | 1445 | is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
|
1445 |
| - // Whether empty patterns can be omitted for exhaustiveness. |
1446 |
| - let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on(); |
1447 |
| - // Whether empty patterns are counted as useful or not. |
1448 |
| - let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms; |
| 1446 | + // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if |
| 1447 | + // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`). |
| 1448 | + let empty_arms_are_unreachable = place_validity.is_known_valid() |
| 1449 | + && (is_toplevel_exception |
| 1450 | + || mcx.tycx.is_exhaustive_patterns_feature_on() |
| 1451 | + || mcx.tycx.is_min_exhaustive_patterns_feature_on()); |
| 1452 | + // Whether empty patterns can be omitted for exhaustiveness. We ignore place validity in the |
| 1453 | + // toplevel exception and `exhaustive_patterns` cases for backwards compatibility. |
| 1454 | + let can_omit_empty_arms = empty_arms_are_unreachable |
| 1455 | + || is_toplevel_exception |
| 1456 | + || mcx.tycx.is_exhaustive_patterns_feature_on(); |
1449 | 1457 |
|
1450 | 1458 | // Analyze the constructors present in this column.
|
1451 | 1459 | let ctors = matrix.heads().map(|p| p.ctor());
|
|
0 commit comments