From 4ed9a7365c04ed0676af9e9088eab9bcd363b9b5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Jan 2024 23:08:31 +0100 Subject: [PATCH] Simplify empty pattern logic some more --- compiler/rustc_pattern_analysis/src/usefulness.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 2ed8f858700c..8a7dd38b1042 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -1363,23 +1363,19 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors); // Whether empty patterns can be omitted for exhaustiveness. let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on(); + // Whether empty patterns are counted as useful or not. + let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms; // Analyze the constructors present in this column. let ctors = matrix.heads().map(|p| p.ctor()); let mut split_set = ctors_for_ty.split(ctors); - if !can_omit_empty_arms { - // Treat all missing constructors as nonempty. - // This clears `missing_empty`. - split_set.missing.append(&mut split_set.missing_empty); - } let all_missing = split_set.present.is_empty(); - // Build the set of constructors we will specialize with. It must cover the whole type. // We need to iterate over a full set of constructors, so we add `Missing` to represent the // missing ones. This is explained under "Constructor Splitting" at the top of this file. let mut split_ctors = split_set.present; if !(split_set.missing.is_empty() - && (split_set.missing_empty.is_empty() || place_validity.is_known_valid())) + && (split_set.missing_empty.is_empty() || empty_arms_are_unreachable)) { split_ctors.push(Constructor::Missing); } @@ -1392,7 +1388,10 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( // Which constructors are considered missing. We ensure that `!missing_ctors.is_empty() => // split_ctors.contains(Missing)`. The converse usually holds except when // `!place_validity.is_known_valid()`. - let missing_ctors = split_set.missing; + let mut missing_ctors = split_set.missing; + if !can_omit_empty_arms { + missing_ctors.append(&mut split_set.missing_empty); + } let mut ret = WitnessMatrix::empty(); for ctor in split_ctors {