Skip to content

Commit a92a331

Browse files
committed
Implement feature gate logic
1 parent ce24238 commit a92a331

File tree

7 files changed

+793
-144
lines changed

7 files changed

+793
-144
lines changed

Diff for: compiler/rustc_pattern_analysis/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub trait TypeCx: Sized + fmt::Debug {
9595
type PatData: Clone;
9696

9797
fn is_exhaustive_patterns_feature_on(&self) -> bool;
98+
fn is_min_exhaustive_patterns_feature_on(&self) -> bool;
9899

99100
/// The number of fields for this constructor.
100101
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: Self::Ty) -> usize;

Diff for: compiler/rustc_pattern_analysis/src/rustc.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
182182
// `field.ty()` doesn't normalize after substituting.
183183
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
184184
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
185-
let is_uninhabited = cx.tcx.features().exhaustive_patterns && cx.is_uninhabited(ty);
185+
let is_uninhabited = (cx.tcx.features().exhaustive_patterns
186+
|| cx.tcx.features().min_exhaustive_patterns)
187+
&& cx.is_uninhabited(ty);
186188

187189
if is_uninhabited && (!is_visible || is_non_exhaustive) {
188190
None
@@ -960,6 +962,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
960962
fn is_exhaustive_patterns_feature_on(&self) -> bool {
961963
self.tcx.features().exhaustive_patterns
962964
}
965+
fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
966+
self.tcx.features().min_exhaustive_patterns
967+
}
963968

964969
fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: Self::Ty) -> usize {
965970
self.ctor_arity(ctor, ty)

Diff for: compiler/rustc_pattern_analysis/src/usefulness.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1439,10 +1439,19 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
14391439
// We treat match scrutinees of type `!` or `EmptyEnum` differently.
14401440
let is_toplevel_exception =
14411441
is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
1442-
// Whether empty patterns can be omitted for exhaustiveness.
1443-
let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on();
1444-
// Whether empty patterns are counted as useful or not.
1445-
let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms;
1442+
// Whether empty patterns can be omitted for exhaustiveness. Empty arms on a `!known_valid`
1443+
// place are not guaranteed unreachable by the operational semantics, but we allow omitting them
1444+
// in some cases nonetheless.
1445+
let can_omit_empty_arms = is_toplevel_exception
1446+
|| mcx.tycx.is_exhaustive_patterns_feature_on()
1447+
|| (mcx.tycx.is_min_exhaustive_patterns_feature_on() && place_validity.is_known_valid());
1448+
// Whether empty patterns are counted as useful or not. Unlike for omitting arms, we only warn
1449+
// an arm unreachable if it is guaranteed unreachable by the opsem (i.e. if the place is
1450+
// `known_valid`).
1451+
let empty_arms_are_unreachable = place_validity.is_known_valid()
1452+
&& (is_toplevel_exception
1453+
|| mcx.tycx.is_exhaustive_patterns_feature_on()
1454+
|| mcx.tycx.is_min_exhaustive_patterns_feature_on());
14461455

14471456
// Analyze the constructors present in this column.
14481457
let ctors = matrix.heads().map(|p| p.ctor());

0 commit comments

Comments
 (0)