Skip to content

Commit 71ba925

Browse files
committed
Stabilize exhaustive patterns.
1 parent f4b80ca commit 71ba925

File tree

56 files changed

+107
-801
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+107
-801
lines changed

compiler/rustc_feature/src/accepted.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ declare_features! (
154154
(accepted, dyn_trait, "1.27.0", Some(44662), None),
155155
/// Allows integer match exhaustiveness checking (RFC 2591).
156156
(accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
157+
/// Allows exhaustive pattern matching on types that contain uninhabited types.
158+
(accepted, exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(51085), None),
157159
/// Allows explicit generic arguments specification with `impl Trait` present.
158160
(accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701), None),
159161
/// Allows arbitrary expressions in key-value attributes at parse time.

compiler/rustc_feature/src/active.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,6 @@ declare_features! (
393393
(incomplete, dyn_star, "1.65.0", Some(102425), None),
394394
/// Allows `X..Y` patterns.
395395
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),
396-
/// Allows exhaustive pattern matching on types that contain uninhabited types.
397-
(active, exhaustive_patterns, "1.13.0", Some(51085), None),
398396
/// Allows explicit tail calls via `become` expression.
399397
(incomplete, explicit_tail_calls, "CURRENT_RUSTC_VERSION", Some(112788), None),
400398
/// Allows using `efiapi`, `sysv64` and `win64` as calling convention

compiler/rustc_middle/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#![feature(box_patterns)]
3030
#![feature(core_intrinsics)]
3131
#![feature(discriminant_kind)]
32-
#![feature(exhaustive_patterns)]
32+
#![cfg_attr(bootstrap, feature(exhaustive_patterns))]
3333
#![feature(generators)]
3434
#![feature(get_mut_unchecked)]
3535
#![feature(if_let_guard)]

compiler/rustc_mir_build/src/build/matches/simplify.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
262262
PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
263263
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
264264
i == variant_index || {
265-
self.tcx.features().exhaustive_patterns
266-
&& !v
267-
.inhabited_predicate(self.tcx, adt_def)
268-
.subst(self.tcx, substs)
269-
.apply_ignore_module(self.tcx, self.param_env)
265+
!v.inhabited_predicate(self.tcx, adt_def)
266+
.subst(self.tcx, substs)
267+
.apply_ignore_module(self.tcx, self.param_env)
270268
}
271269
}) && (adt_def.did().is_local()
272270
|| !adt_def.is_variant_list_non_exhaustive());

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
499499
// Emit an extra note if the first uncovered witness would be uninhabited
500500
// if we disregard visibility.
501501
let witness_1_is_privately_uninhabited =
502-
if cx.tcx.features().exhaustive_patterns
503-
&& let Some(witness_1) = witnesses.get(0)
502+
if let Some(witness_1) = witnesses.get(0)
504503
&& let ty::Adt(adt, substs) = witness_1.ty().kind()
505504
&& adt.is_enum()
506505
&& let Constructor::Variant(variant_index) = witness_1.ctor()

compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -902,9 +902,8 @@ impl<'tcx> SplitWildcard<'tcx> {
902902
// This determines the set of all possible constructors for the type `pcx.ty`. For numbers,
903903
// arrays and slices we use ranges and variable-length slices when appropriate.
904904
//
905-
// If the `exhaustive_patterns` feature is enabled, we make sure to omit constructors that
906-
// are statically impossible. E.g., for `Option<!>`, we do not include `Some(_)` in the
907-
// returned list of constructors.
905+
// We omit constructors that are statically impossible. E.g., for `Option<!>`, we do not
906+
// include `Some(_)` in the returned list of constructors.
908907
// Invariant: this is empty if and only if the type is uninhabited (as determined by
909908
// `cx.is_uninhabited()`).
910909
let all_ctors = match pcx.ty.kind() {
@@ -941,32 +940,21 @@ impl<'tcx> SplitWildcard<'tcx> {
941940
// witness.
942941
let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty);
943942

944-
let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns;
945-
946-
// If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
947-
// as though it had an "unknown" constructor to avoid exposing its emptiness. The
948-
// exception is if the pattern is at the top level, because we want empty matches to be
949-
// considered exhaustive.
950-
let is_secretly_empty =
951-
def.variants().is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
952-
953943
let mut ctors: SmallVec<[_; 1]> = def
954944
.variants()
955945
.iter_enumerated()
956946
.filter(|(_, v)| {
957-
// If `exhaustive_patterns` is enabled, we exclude variants known to be
958-
// uninhabited.
959-
!is_exhaustive_pat_feature
960-
|| v.inhabited_predicate(cx.tcx, *def).subst(cx.tcx, substs).apply(
961-
cx.tcx,
962-
cx.param_env,
963-
cx.module,
964-
)
947+
// exclude variants known to be uninhabited.
948+
v.inhabited_predicate(cx.tcx, *def).subst(cx.tcx, substs).apply(
949+
cx.tcx,
950+
cx.param_env,
951+
cx.module,
952+
)
965953
})
966954
.map(|(idx, _)| Variant(idx))
967955
.collect();
968956

969-
if is_secretly_empty || is_declared_nonexhaustive {
957+
if is_declared_nonexhaustive {
970958
ctors.push(NonExhaustive);
971959
}
972960
ctors
@@ -998,12 +986,6 @@ impl<'tcx> SplitWildcard<'tcx> {
998986
let max = size.truncate(u128::MAX);
999987
smallvec![make_range(0, max)]
1000988
}
1001-
// If `exhaustive_patterns` is disabled and our scrutinee is the never type, we cannot
1002-
// expose its emptiness. The exception is if the pattern is at the top level, because we
1003-
// want empty matches to be considered exhaustive.
1004-
ty::Never if !cx.tcx.features().exhaustive_patterns && !pcx.is_top_level => {
1005-
smallvec![NonExhaustive]
1006-
}
1007989
ty::Never => smallvec![],
1008990
_ if cx.is_uninhabited(pcx.ty) => smallvec![],
1009991
ty::Adt(..) | ty::Tuple(..) | ty::Ref(..) => smallvec![Single],

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
340340

341341
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
342342
pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
343-
if self.tcx.features().exhaustive_patterns {
344-
!ty.is_inhabited_from(self.tcx, self.module, self.param_env)
345-
} else {
346-
false
347-
}
343+
!ty.is_inhabited_from(self.tcx, self.module, self.param_env)
348344
}
349345

350346
/// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.

compiler/rustc_target/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1111
#![feature(assert_matches)]
1212
#![feature(associated_type_bounds)]
13-
#![feature(exhaustive_patterns)]
13+
#![cfg_attr(bootstrap, feature(exhaustive_patterns))]
1414
#![feature(iter_intersperse)]
1515
#![feature(min_specialization)]
1616
#![feature(never_type)]

compiler/rustc_traits/src/chalk/lowering.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
552552
),
553553
chalk_ir::LifetimeData::Static => tcx.lifetimes.re_static,
554554
chalk_ir::LifetimeData::Erased => tcx.lifetimes.re_erased,
555+
#[cfg(bootstrap)]
555556
chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
556557
}
557558
}

compiler/rustc_transmute/src/layout/nfa.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ where
8686
pub(crate) fn from_tree(tree: Tree<!, R>) -> Result<Self, Uninhabited> {
8787
Ok(match tree {
8888
Tree::Byte(b) => Self::from_byte(b),
89+
#[cfg(bootstrap)]
8990
Tree::Def(..) => unreachable!(),
9091
Tree::Ref(r) => Self::from_ref(r),
9192
Tree::Alt(alts) => {

0 commit comments

Comments
 (0)