diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 0170d52e82a2e..ea5ec13135ea0 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -154,6 +154,8 @@ declare_features! ( (accepted, dyn_trait, "1.27.0", Some(44662), None), /// Allows integer match exhaustiveness checking (RFC 2591). (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), + /// Allows exhaustive pattern matching on types that contain uninhabited types. + (accepted, exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(51085), None), /// Allows explicit generic arguments specification with `impl Trait` present. (accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701), None), /// Allows arbitrary expressions in key-value attributes at parse time. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 906c31c9a3def..bf62a2f8e026f 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -393,8 +393,6 @@ declare_features! ( (incomplete, dyn_star, "1.65.0", Some(102425), None), /// Allows `X..Y` patterns. (active, exclusive_range_pattern, "1.11.0", Some(37854), None), - /// Allows exhaustive pattern matching on types that contain uninhabited types. - (active, exhaustive_patterns, "1.13.0", Some(51085), None), /// Allows explicit tail calls via `become` expression. (incomplete, explicit_tail_calls, "CURRENT_RUSTC_VERSION", Some(112788), None), /// Allows using `efiapi`, `sysv64` and `win64` as calling convention diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 1b125e8e26dbc..d45b716ac45f9 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,7 +29,7 @@ #![feature(box_patterns)] #![feature(core_intrinsics)] #![feature(discriminant_kind)] -#![feature(exhaustive_patterns)] +#![cfg_attr(bootstrap, feature(exhaustive_patterns))] #![feature(generators)] #![feature(get_mut_unchecked)] #![feature(if_let_guard)] diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index f6b1955fdec4d..af25788d4da63 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -262,11 +262,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index || { - self.tcx.features().exhaustive_patterns - && !v - .inhabited_predicate(self.tcx, adt_def) - .subst(self.tcx, substs) - .apply_ignore_module(self.tcx, self.param_env) + !v.inhabited_predicate(self.tcx, adt_def) + .subst(self.tcx, substs) + .apply_ignore_module(self.tcx, self.param_env) } }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index ef60f08bf020b..189758f60ae51 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -499,8 +499,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { // Emit an extra note if the first uncovered witness would be uninhabited // if we disregard visibility. let witness_1_is_privately_uninhabited = - if cx.tcx.features().exhaustive_patterns - && let Some(witness_1) = witnesses.get(0) + if let Some(witness_1) = witnesses.get(0) && let ty::Adt(adt, substs) = witness_1.ty().kind() && adt.is_enum() && let Constructor::Variant(variant_index) = witness_1.ctor() diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 9df6d2f43ad57..516d7ccc5e12e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -902,9 +902,8 @@ impl<'tcx> SplitWildcard<'tcx> { // This determines the set of all possible constructors for the type `pcx.ty`. For numbers, // arrays and slices we use ranges and variable-length slices when appropriate. // - // If the `exhaustive_patterns` feature is enabled, we make sure to omit constructors that - // are statically impossible. E.g., for `Option`, we do not include `Some(_)` in the - // returned list of constructors. + // We omit constructors that are statically impossible. E.g., for `Option`, we do not + // include `Some(_)` in the returned list of constructors. // Invariant: this is empty if and only if the type is uninhabited (as determined by // `cx.is_uninhabited()`). let all_ctors = match pcx.ty.kind() { @@ -941,32 +940,21 @@ impl<'tcx> SplitWildcard<'tcx> { // witness. let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty); - let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns; - - // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it - // as though it had an "unknown" constructor to avoid exposing its emptiness. The - // exception is if the pattern is at the top level, because we want empty matches to be - // considered exhaustive. - let is_secretly_empty = - def.variants().is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level; - let mut ctors: SmallVec<[_; 1]> = def .variants() .iter_enumerated() .filter(|(_, v)| { - // If `exhaustive_patterns` is enabled, we exclude variants known to be - // uninhabited. - !is_exhaustive_pat_feature - || v.inhabited_predicate(cx.tcx, *def).subst(cx.tcx, substs).apply( - cx.tcx, - cx.param_env, - cx.module, - ) + // exclude variants known to be uninhabited. + v.inhabited_predicate(cx.tcx, *def).subst(cx.tcx, substs).apply( + cx.tcx, + cx.param_env, + cx.module, + ) }) .map(|(idx, _)| Variant(idx)) .collect(); - if is_secretly_empty || is_declared_nonexhaustive { + if is_declared_nonexhaustive { ctors.push(NonExhaustive); } ctors @@ -998,12 +986,6 @@ impl<'tcx> SplitWildcard<'tcx> { let max = size.truncate(u128::MAX); smallvec![make_range(0, max)] } - // If `exhaustive_patterns` is disabled and our scrutinee is the never type, we cannot - // expose its emptiness. The exception is if the pattern is at the top level, because we - // want empty matches to be considered exhaustive. - ty::Never if !cx.tcx.features().exhaustive_patterns && !pcx.is_top_level => { - smallvec![NonExhaustive] - } ty::Never => smallvec![], _ if cx.is_uninhabited(pcx.ty) => smallvec![], ty::Adt(..) | ty::Tuple(..) | ty::Ref(..) => smallvec![Single], diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index e5b6350690609..8d44a65555c6f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -340,11 +340,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> { impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { - if self.tcx.features().exhaustive_patterns { - !ty.is_inhabited_from(self.tcx, self.module, self.param_env) - } else { - false - } + !ty.is_inhabited_from(self.tcx, self.module, self.param_env) } /// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`. diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index a7b54766bc623..d28b25f486891 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -10,7 +10,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(assert_matches)] #![feature(associated_type_bounds)] -#![feature(exhaustive_patterns)] +#![cfg_attr(bootstrap, feature(exhaustive_patterns))] #![feature(iter_intersperse)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index b7db56d3db8a2..c88bd5f8724ab 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -552,6 +552,7 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime tcx.lifetimes.re_static, chalk_ir::LifetimeData::Erased => tcx.lifetimes.re_erased, + #[cfg(bootstrap)] chalk_ir::LifetimeData::Phantom(void, _) => match *void {}, } } diff --git a/compiler/rustc_transmute/src/layout/nfa.rs b/compiler/rustc_transmute/src/layout/nfa.rs index 78fcceb5f2cb5..654b7d67f4cdb 100644 --- a/compiler/rustc_transmute/src/layout/nfa.rs +++ b/compiler/rustc_transmute/src/layout/nfa.rs @@ -86,6 +86,7 @@ where pub(crate) fn from_tree(tree: Tree) -> Result { Ok(match tree { Tree::Byte(b) => Self::from_byte(b), + #[cfg(bootstrap)] Tree::Def(..) => unreachable!(), Tree::Ref(r) => Self::from_ref(r), Tree::Alt(alts) => { diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index d9e274df0f5f2..e9aefa09aa9ef 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -120,6 +120,7 @@ impl Iterator for IntoIter { { match self.try_fold(init, |b, item| Ok::(f(b, item))) { Ok(b) => b, + #[cfg(bootstrap)] Err(e) => match e {}, } } @@ -241,6 +242,7 @@ impl DoubleEndedIterator for IntoIter { { match self.try_rfold(init, |b, item| Ok::(f(b, item))) { Ok(b) => b, + #[cfg(bootstrap)] Err(e) => match e {}, } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 05876f5fc581b..2dcbf393a75f4 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -183,6 +183,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(exhaustive_patterns))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -206,7 +207,6 @@ #![feature(doc_cfg)] #![feature(doc_cfg_hide)] #![feature(doc_notable_trait)] -#![feature(exhaustive_patterns)] #![feature(extern_types)] #![feature(fundamental)] #![feature(generic_arg_infer)] diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 80289ca08c3fc..5cb408c726cf9 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -130,15 +130,14 @@ mod prim_bool {} /// [`Result`] which we can unpack like this: /// /// ``` -/// #![feature(exhaustive_patterns)] +/// # #![cfg_attr(bootstrap, feature(exhaustive_patterns))] /// use std::str::FromStr; /// let Ok(s) = String::from_str("hello"); /// ``` /// -/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns` -/// feature is present this means we can exhaustively match on [`Result`] by just taking the -/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain -/// enum variants from generic types like `Result`. +/// Since the [`Err`] variant contains a `!`, it can never occur. This means we can exhaustively +/// match on [`Result`] by just taking the [`Ok`] variant. This illustrates another behaviour +/// of `!` - it can be used to "delete" certain enum variants from generic types like `Result`. /// /// ## Infinite loops /// diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index da08c018d0e36..e2e1244029842 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -237,6 +237,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(exhaustive_patterns))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] @@ -254,7 +255,6 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] -#![feature(exhaustive_patterns)] #![feature(if_let_guard)] #![feature(intra_doc_pointers)] #![feature(lang_items)] diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 80289ca08c3fc..5cb408c726cf9 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -130,15 +130,14 @@ mod prim_bool {} /// [`Result`] which we can unpack like this: /// /// ``` -/// #![feature(exhaustive_patterns)] +/// # #![cfg_attr(bootstrap, feature(exhaustive_patterns))] /// use std::str::FromStr; /// let Ok(s) = String::from_str("hello"); /// ``` /// -/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns` -/// feature is present this means we can exhaustively match on [`Result`] by just taking the -/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain -/// enum variants from generic types like `Result`. +/// Since the [`Err`] variant contains a `!`, it can never occur. This means we can exhaustively +/// match on [`Result`] by just taking the [`Ok`] variant. This illustrates another behaviour +/// of `!` - it can be used to "delete" certain enum variants from generic types like `Result`. /// /// ## Infinite loops /// diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed index e396ae94aaab2..7d5d443586cff 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed @@ -1,5 +1,5 @@ //@run-rustfix -#![feature(exhaustive_patterns, never_type)] +#![feature(never_type)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs index 3fce7bbb6c712..ff4da0ac8ad3a 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs @@ -1,5 +1,5 @@ //@run-rustfix -#![feature(exhaustive_patterns, never_type)] +#![feature(never_type)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed index f88498655a418..4d9a55758c79a 100644 --- a/src/tools/clippy/tests/ui/single_match_else.fixed +++ b/src/tools/clippy/tests/ui/single_match_else.fixed @@ -2,6 +2,7 @@ //@aux-build: proc_macros.rs #![warn(clippy::single_match_else)] #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] +#![allow(irrefutable_let_patterns)] // The fixed code may introduce some cases. extern crate proc_macros; use proc_macros::with_span; diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs index b34b95539190c..a624b7121c9c1 100644 --- a/src/tools/clippy/tests/ui/single_match_else.rs +++ b/src/tools/clippy/tests/ui/single_match_else.rs @@ -2,6 +2,7 @@ //@aux-build: proc_macros.rs #![warn(clippy::single_match_else)] #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] +#![allow(irrefutable_let_patterns)] // The fixed code may introduce some cases. extern crate proc_macros; use proc_macros::with_span; diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr index 228236f3bb8e8..453cbc63f63a8 100644 --- a/src/tools/clippy/tests/ui/single_match_else.stderr +++ b/src/tools/clippy/tests/ui/single_match_else.stderr @@ -1,5 +1,5 @@ error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:17:13 + --> $DIR/single_match_else.rs:18:13 | LL | let _ = match ExprNode::Butterflies { | _____________^ @@ -21,7 +21,7 @@ LL ~ }; | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:82:5 + --> $DIR/single_match_else.rs:83:5 | LL | / match Some(1) { LL | | Some(a) => println!("${:?}", a), @@ -41,7 +41,7 @@ LL + } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:91:5 + --> $DIR/single_match_else.rs:92:5 | LL | / match Some(1) { LL | | Some(a) => println!("${:?}", a), @@ -61,7 +61,7 @@ LL + } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:101:5 + --> $DIR/single_match_else.rs:102:5 | LL | / match Result::::Ok(1) { LL | | Ok(a) => println!("${:?}", a), @@ -81,7 +81,7 @@ LL + } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:110:5 + --> $DIR/single_match_else.rs:111:5 | LL | / match Cow::from("moo") { LL | | Cow::Owned(a) => println!("${:?}", a), @@ -101,7 +101,7 @@ LL + } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:120:5 + --> $DIR/single_match_else.rs:121:5 | LL | / match bar { LL | | Some(v) => unsafe { @@ -124,7 +124,7 @@ LL + } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:131:5 + --> $DIR/single_match_else.rs:132:5 | LL | / match bar { LL | | Some(v) => { @@ -148,7 +148,7 @@ LL + } } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:143:5 + --> $DIR/single_match_else.rs:144:5 | LL | / match bar { LL | | Some(v) => unsafe { @@ -172,7 +172,7 @@ LL + } } | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:155:5 + --> $DIR/single_match_else.rs:156:5 | LL | / match bar { LL | | #[rustfmt::skip] diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 91e004e010624..cb7a189d62382 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -443,6 +443,7 @@ pub fn eval_entry<'tcx>( let res = match res { Err(res) => res, // `Ok` can never happen + #[cfg(bootstrap)] Ok(never) => match never {}, }; diff --git a/src/tools/miri/src/shims/unix/dlsym.rs b/src/tools/miri/src/shims/unix/dlsym.rs index 8bc19d18f2b29..6d21c5cd39f96 100644 --- a/src/tools/miri/src/shims/unix/dlsym.rs +++ b/src/tools/miri/src/shims/unix/dlsym.rs @@ -46,8 +46,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { match dlsym { Dlsym::Android(dlsym) => android::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret), + #[cfg(bootstrap)] Dlsym::FreeBsd(dlsym) => freebsd::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret), + #[cfg(bootstrap)] Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret), Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret), } diff --git a/src/tools/miri/tests/pass/enums.rs b/src/tools/miri/tests/pass/enums.rs index ac7aafc1bb2e3..a82fcffea05a9 100644 --- a/src/tools/miri/tests/pass/enums.rs +++ b/src/tools/miri/tests/pass/enums.rs @@ -102,6 +102,7 @@ fn more_discriminant_overflow() { V4, } + #[allow(unreachable_patterns)] if let E1::V2 { .. } = (E1::V1 { f: true }) { unreachable!() } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs index a0f6b9368ee01..4a1d264dc1863 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs @@ -41,6 +41,9 @@ //! or-patterns; instead we just try the alternatives one-by-one. For details on splitting //! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]. +// This uses uninhabited types to encode statically unused variants. +#![allow(unreachable_patterns)] + use std::{ cell::Cell, cmp::{max, min}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index c1df24d17291e..345ae8e2d99fc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1620,6 +1620,7 @@ impl HirDisplay for LifetimeData { } LifetimeData::Static => write!(f, "'static"), LifetimeData::Erased => Ok(()), + #[allow(unreachable_patterns)] LifetimeData::Phantom(_, _) => Ok(()), } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index ff64ae252bce9..7cc3e5dc3b00d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -214,6 +214,7 @@ impl CapturedItem { result = format!("{result}.{field}"); field_need_paren = false; } + #[allow(unreachable_patterns)] ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 3b9ef03c369f4..f0a76155efa5d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -9,6 +9,7 @@ macro_rules! from_bytes { ($ty:tt, $value:expr) => { ($ty::from_le_bytes(match ($value).try_into() { Ok(x) => x, + #[allow(unreachable_patterns)] Err(_) => return Err(MirEvalError::TypeError("mismatched size")), })) }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 2cb29b4ab91de..3ee46aa336fe9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1028,6 +1028,7 @@ impl<'ctx> MirLowerCtx<'ctx> { ProjectionElem::ConstantIndex { offset, from_end } => ProjectionElem::ConstantIndex { offset, from_end }, ProjectionElem::Subslice { from, to } => ProjectionElem::Subslice { from, to }, ProjectionElem::OpaqueCast(x) => ProjectionElem::OpaqueCast(x), + #[allow(unreachable_patterns)] ProjectionElem::Index(x) => match x { }, } }).collect(), diff --git a/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 474f43104bb43..b29b6d8fd2c04 100644 --- a/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -17,10 +17,6 @@ fn main() -> () { StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); - switchInt(move _3) -> [2: bb1, otherwise: bb2]; - } - - bb1: { StorageLive(_5); _5 = const "C"; _1 = &(*_5); @@ -31,27 +27,27 @@ fn main() -> () { StorageLive(_7); _7 = Test2::D; _8 = discriminant(_7); - switchInt(move _8) -> [4: bb4, 5: bb3, otherwise: bb2]; - } - - bb2: { - unreachable; + switchInt(move _8) -> [4: bb3, 5: bb1, otherwise: bb2]; } - bb3: { + bb1: { StorageLive(_9); _9 = const "E"; _6 = &(*_9); StorageDead(_9); - goto -> bb5; + goto -> bb4; } - bb4: { + bb2: { + unreachable; + } + + bb3: { _6 = const "D"; - goto -> bb5; + goto -> bb4; } - bb5: { + bb4: { StorageDead(_7); StorageDead(_6); _0 = const (); diff --git a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff index 9db95abec34c8..71c9cc6458cd0 100644 --- a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -18,8 +18,8 @@ StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); -- switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb1, otherwise: bb2]; -+ switchInt(move _3) -> [2: bb1, otherwise: bb2]; +- switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; ++ switchInt(move _3) -> bb1; } bb1: { @@ -27,37 +27,33 @@ _5 = const "C"; _1 = &(*_5); StorageDead(_5); - goto -> bb5; + goto -> bb4; } bb2: { - unreachable; - } - - bb3: { _1 = const "A(Empty)"; - goto -> bb5; + goto -> bb4; } - bb4: { + bb3: { StorageLive(_4); _4 = const "B(Empty)"; _1 = &(*_4); StorageDead(_4); - goto -> bb5; + goto -> bb4; } - bb5: { + bb4: { StorageDead(_2); StorageDead(_1); StorageLive(_6); StorageLive(_7); _7 = Test2::D; _8 = discriminant(_7); - switchInt(move _8) -> [4: bb7, 5: bb6, otherwise: bb2]; + switchInt(move _8) -> [4: bb7, 5: bb5, otherwise: bb6]; } - bb6: { + bb5: { StorageLive(_9); _9 = const "E"; _6 = &(*_9); @@ -65,6 +61,10 @@ goto -> bb8; } + bb6: { + unreachable; + } + bb7: { _6 = const "D"; goto -> bb8; diff --git a/tests/ui/binding/empty-types-in-patterns.rs b/tests/ui/binding/empty-types-in-patterns.rs index 0d0dbcaf40f43..0ba4051bac9ae 100644 --- a/tests/ui/binding/empty-types-in-patterns.rs +++ b/tests/ui/binding/empty-types-in-patterns.rs @@ -1,7 +1,6 @@ // run-pass #![feature(never_type, never_type_fallback)] -#![feature(exhaustive_patterns)] #![allow(unreachable_patterns)] #![allow(unreachable_code)] diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs index 72652ef60349a..c1a9861575dca 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs @@ -2,7 +2,6 @@ // visibly uninhabited). // edition:2021 // run-pass -#![feature(exhaustive_patterns)] #![feature(never_type)] pub fn main() { diff --git a/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs b/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs index cccb7879fc0fb..2df10ac795f50 100644 --- a/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs +++ b/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs @@ -1,6 +1,7 @@ // run-pass #![allow(dead_code)] +#![allow(unreachable_patterns)] enum Empty { } enum Test1 { diff --git a/tests/ui/enum-discriminant/issue-61696.rs b/tests/ui/enum-discriminant/issue-61696.rs index 8a633a916c838..f97469657efe5 100644 --- a/tests/ui/enum-discriminant/issue-61696.rs +++ b/tests/ui/enum-discriminant/issue-61696.rs @@ -1,5 +1,7 @@ // run-pass +#![allow(unreachable_patterns)] + pub enum Infallible {} // The check that the `bool` field of `V1` is encoding a "niche variant" diff --git a/tests/ui/enum-discriminant/niche.rs b/tests/ui/enum-discriminant/niche.rs index 8d30610504f7d..aa7b9cc26a4b0 100644 --- a/tests/ui/enum-discriminant/niche.rs +++ b/tests/ui/enum-discriminant/niche.rs @@ -1,5 +1,7 @@ // run-pass +#![allow(unreachable_patterns)] + //! Make sure that we read and write enum discriminants correctly for corner cases caused //! by layout optimizations. diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.rs deleted file mode 100644 index f0cc9ea70550e..0000000000000 --- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(never_type)] - -fn foo() -> Result { - Ok(123) -} - -fn main() { - let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding -} diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr deleted file mode 100644 index 49e7ab6082c82..0000000000000 --- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0005]: refutable pattern in local binding - --> $DIR/feature-gate-exhaustive-patterns.rs:8:9 - | -LL | let Ok(_x) = foo(); - | ^^^^^^ pattern `Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html - = note: the matched value is of type `Result` -help: you might want to use `let else` to handle the variant that isn't matched - | -LL | let Ok(_x) = foo() else { todo!() }; - | ++++++++++++++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0005`. diff --git a/tests/ui/never_type/const-in-pattern.rs b/tests/ui/never_type/const-in-pattern.rs new file mode 100644 index 0000000000000..dc0403eda4e47 --- /dev/null +++ b/tests/ui/never_type/const-in-pattern.rs @@ -0,0 +1,16 @@ +// Check that we emit an error when an erroneous constant is used in a pattern, even if this +// pattern is uninhabited. + +#![feature(never_type)] +#![feature(inline_const_pat)] +//~^ WARN the feature `inline_const_pat` is incomplete + +fn foo(x: Result) -> T { + match x { + Ok(y) => y, + Err(const { panic!() }) => panic!(), + //~^ ERROR evaluation of `foo::::{constant#0}` failed + } +} + +fn main() {} diff --git a/tests/ui/never_type/const-in-pattern.stderr b/tests/ui/never_type/const-in-pattern.stderr new file mode 100644 index 0000000000000..3cdefb53def5b --- /dev/null +++ b/tests/ui/never_type/const-in-pattern.stderr @@ -0,0 +1,20 @@ +warning: the feature `inline_const_pat` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-in-pattern.rs:5:12 + | +LL | #![feature(inline_const_pat)] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #76001 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0080]: evaluation of `foo::::{constant#0}` failed + --> $DIR/const-in-pattern.rs:11:21 + | +LL | Err(const { panic!() }) => panic!(), + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const-in-pattern.rs:11:21 + | + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/never_type/exhaustive_patterns.rs b/tests/ui/never_type/exhaustive_patterns.rs index 2e23fa1828091..e9917bd79ad76 100644 --- a/tests/ui/never_type/exhaustive_patterns.rs +++ b/tests/ui/never_type/exhaustive_patterns.rs @@ -1,7 +1,4 @@ -// check-fail -// known-bug: #104034 - -#![feature(exhaustive_patterns, never_type)] +#![feature(never_type)] mod inner { pub struct Wrapper(T); @@ -18,4 +15,5 @@ fn foo() -> Either<(), !> { fn main() { let Either::A(()) = foo(); + //~^ ERROR refutable pattern in local binding } diff --git a/tests/ui/never_type/exhaustive_patterns.stderr b/tests/ui/never_type/exhaustive_patterns.stderr index f7bf858158231..0025e892ea2c7 100644 --- a/tests/ui/never_type/exhaustive_patterns.stderr +++ b/tests/ui/never_type/exhaustive_patterns.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/exhaustive_patterns.rs:20:9 + --> $DIR/exhaustive_patterns.rs:17:9 | LL | let Either::A(()) = foo(); | ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered @@ -7,7 +7,7 @@ LL | let Either::A(()) = foo(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html note: `Either<(), !>` defined here - --> $DIR/exhaustive_patterns.rs:10:6 + --> $DIR/exhaustive_patterns.rs:7:6 | LL | enum Either { | ^^^^^^ diff --git a/tests/ui/never_type/issue-44402.rs b/tests/ui/never_type/issue-44402.rs index 699e480dfe7e5..fdb0721adbdc8 100644 --- a/tests/ui/never_type/issue-44402.rs +++ b/tests/ui/never_type/issue-44402.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] #![feature(never_type)] -#![feature(exhaustive_patterns)] // Regression test for inhabitedness check. The old // cache used to cause us to incorrectly decide diff --git a/tests/ui/never_type/never-result.rs b/tests/ui/never_type/never-result.rs index 35af37910ef3e..0b9b4b3d746fb 100644 --- a/tests/ui/never_type/never-result.rs +++ b/tests/ui/never_type/never-result.rs @@ -2,6 +2,7 @@ #![allow(unused_variables)] #![allow(unreachable_code)] +#![allow(unreachable_patterns)] // Test that we can extract a ! through pattern matching then use it as several different types. diff --git a/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs b/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs index 7d1cac8a442f5..b220a55849fcb 100644 --- a/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs +++ b/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs @@ -1,7 +1,6 @@ // The precise semantics of inhabitedness with respect to unions and references is currently // undecided. This test file currently checks a conservative choice. -#![feature(exhaustive_patterns)] #![feature(never_type)] #![allow(dead_code)] diff --git a/tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr index cd5c283f9fd93..9000176f58841 100644 --- a/tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr +++ b/tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/always-inhabited-union-ref.rs:23:11 + --> $DIR/always-inhabited-union-ref.rs:22:11 | LL | match uninhab_ref() { | ^^^^^^^^^^^^^ @@ -14,13 +14,13 @@ LL + } | error[E0004]: non-exhaustive patterns: type `Foo` is non-empty - --> $DIR/always-inhabited-union-ref.rs:27:11 + --> $DIR/always-inhabited-union-ref.rs:26:11 | LL | match uninhab_union() { | ^^^^^^^^^^^^^^^ | note: `Foo` defined here - --> $DIR/always-inhabited-union-ref.rs:10:11 + --> $DIR/always-inhabited-union-ref.rs:9:11 | LL | pub union Foo { | ^^^ diff --git a/tests/ui/pattern/usefulness/empty-match.rs b/tests/ui/pattern/usefulness/empty-match.rs index d56d2e3c817ce..101813dd4d263 100644 --- a/tests/ui/pattern/usefulness/empty-match.rs +++ b/tests/ui/pattern/usefulness/empty-match.rs @@ -1,10 +1,8 @@ // aux-build:empty.rs -// revisions: normal exhaustive_patterns // // This tests a match with no arms on various types. #![feature(never_type)] #![feature(never_type_fallback)] -#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] #![deny(unreachable_patterns)] //~^ NOTE the lint level is defined here @@ -79,7 +77,7 @@ fn empty_foreign_enum_private(x: Option //~| NOTE for more information, visit //~| NOTE the matched value is of type //~| NOTE pattern `Some(_)` not covered - //[exhaustive_patterns]~| NOTE currently uninhabited, but this variant contains private fields + //~| NOTE currently uninhabited, but this variant contains private fields } fn never(x: !) { diff --git a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match.stderr similarity index 91% rename from tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr rename to tests/ui/pattern/usefulness/empty-match.stderr index 5b81a8c3d3c02..78b4698e01e8f 100644 --- a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-match.stderr @@ -1,35 +1,35 @@ error: unreachable pattern - --> $DIR/empty-match.rs:58:9 + --> $DIR/empty-match.rs:56:9 | LL | _ => {}, | ^ | note: the lint level is defined here - --> $DIR/empty-match.rs:8:9 + --> $DIR/empty-match.rs:6:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-match.rs:61:9 + --> $DIR/empty-match.rs:59:9 | LL | _ if false => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:68:9 + --> $DIR/empty-match.rs:66:9 | LL | _ => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:71:9 + --> $DIR/empty-match.rs:69:9 | LL | _ if false => {}, | ^ error[E0005]: refutable pattern in local binding - --> $DIR/empty-match.rs:76:9 + --> $DIR/empty-match.rs:74:9 | LL | let None = x; | ^^^^ pattern `Some(_)` not covered @@ -44,19 +44,19 @@ LL | if let None = x { todo!() }; | ++ +++++++++++ error: unreachable pattern - --> $DIR/empty-match.rs:88:9 + --> $DIR/empty-match.rs:86:9 | LL | _ => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:91:9 + --> $DIR/empty-match.rs:89:9 | LL | _ if false => {}, | ^ error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/empty-match.rs:109:20 + --> $DIR/empty-match.rs:107:20 | LL | match_no_arms!(0u8); | ^^^ @@ -65,13 +65,13 @@ LL | match_no_arms!(0u8); = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty - --> $DIR/empty-match.rs:111:20 + --> $DIR/empty-match.rs:109:20 | LL | match_no_arms!(NonEmptyStruct1); | ^^^^^^^^^^^^^^^ | note: `NonEmptyStruct1` defined here - --> $DIR/empty-match.rs:15:8 + --> $DIR/empty-match.rs:13:8 | LL | struct NonEmptyStruct1; | ^^^^^^^^^^^^^^^ @@ -79,13 +79,13 @@ LL | struct NonEmptyStruct1; = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty - --> $DIR/empty-match.rs:113:20 + --> $DIR/empty-match.rs:111:20 | LL | match_no_arms!(NonEmptyStruct2(true)); | ^^^^^^^^^^^^^^^^^^^^^ | note: `NonEmptyStruct2` defined here - --> $DIR/empty-match.rs:18:8 + --> $DIR/empty-match.rs:16:8 | LL | struct NonEmptyStruct2(bool); | ^^^^^^^^^^^^^^^ @@ -93,13 +93,13 @@ LL | struct NonEmptyStruct2(bool); = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty - --> $DIR/empty-match.rs:115:20 + --> $DIR/empty-match.rs:113:20 | LL | match_no_arms!((NonEmptyUnion1 { foo: () })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `NonEmptyUnion1` defined here - --> $DIR/empty-match.rs:21:7 + --> $DIR/empty-match.rs:19:7 | LL | union NonEmptyUnion1 { | ^^^^^^^^^^^^^^ @@ -107,13 +107,13 @@ LL | union NonEmptyUnion1 { = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty - --> $DIR/empty-match.rs:117:20 + --> $DIR/empty-match.rs:115:20 | LL | match_no_arms!((NonEmptyUnion2 { foo: () })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `NonEmptyUnion2` defined here - --> $DIR/empty-match.rs:26:7 + --> $DIR/empty-match.rs:24:7 | LL | union NonEmptyUnion2 { | ^^^^^^^^^^^^^^ @@ -121,13 +121,13 @@ LL | union NonEmptyUnion2 { = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered - --> $DIR/empty-match.rs:119:20 + --> $DIR/empty-match.rs:117:20 | LL | match_no_arms!(NonEmptyEnum1::Foo(true)); | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered | note: `NonEmptyEnum1` defined here - --> $DIR/empty-match.rs:33:5 + --> $DIR/empty-match.rs:31:5 | LL | enum NonEmptyEnum1 { | ------------- @@ -137,13 +137,13 @@ LL | Foo(bool), = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered - --> $DIR/empty-match.rs:122:20 + --> $DIR/empty-match.rs:120:20 | LL | match_no_arms!(NonEmptyEnum2::Foo(true)); | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered | note: `NonEmptyEnum2` defined here - --> $DIR/empty-match.rs:40:5 + --> $DIR/empty-match.rs:38:5 | LL | enum NonEmptyEnum2 { | ------------- @@ -156,13 +156,13 @@ LL | Bar, = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered - --> $DIR/empty-match.rs:125:20 + --> $DIR/empty-match.rs:123:20 | LL | match_no_arms!(NonEmptyEnum5::V1); | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered | note: `NonEmptyEnum5` defined here - --> $DIR/empty-match.rs:49:6 + --> $DIR/empty-match.rs:47:6 | LL | enum NonEmptyEnum5 { | ^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL | enum NonEmptyEnum5 { = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/empty-match.rs:129:24 + --> $DIR/empty-match.rs:127:24 | LL | match_guarded_arm!(0u8); | ^^^ pattern `_` not covered @@ -184,13 +184,13 @@ LL + _ => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered - --> $DIR/empty-match.rs:134:24 + --> $DIR/empty-match.rs:132:24 | LL | match_guarded_arm!(NonEmptyStruct1); | ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered | note: `NonEmptyStruct1` defined here - --> $DIR/empty-match.rs:15:8 + --> $DIR/empty-match.rs:13:8 | LL | struct NonEmptyStruct1; | ^^^^^^^^^^^^^^^ @@ -203,13 +203,13 @@ LL + NonEmptyStruct1 => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered - --> $DIR/empty-match.rs:139:24 + --> $DIR/empty-match.rs:137:24 | LL | match_guarded_arm!(NonEmptyStruct2(true)); | ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered | note: `NonEmptyStruct2` defined here - --> $DIR/empty-match.rs:18:8 + --> $DIR/empty-match.rs:16:8 | LL | struct NonEmptyStruct2(bool); | ^^^^^^^^^^^^^^^ @@ -222,13 +222,13 @@ LL + NonEmptyStruct2(_) => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered - --> $DIR/empty-match.rs:144:24 + --> $DIR/empty-match.rs:142:24 | LL | match_guarded_arm!((NonEmptyUnion1 { foo: () })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered | note: `NonEmptyUnion1` defined here - --> $DIR/empty-match.rs:21:7 + --> $DIR/empty-match.rs:19:7 | LL | union NonEmptyUnion1 { | ^^^^^^^^^^^^^^ @@ -241,13 +241,13 @@ LL + NonEmptyUnion1 { .. } => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered - --> $DIR/empty-match.rs:149:24 + --> $DIR/empty-match.rs:147:24 | LL | match_guarded_arm!((NonEmptyUnion2 { foo: () })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered | note: `NonEmptyUnion2` defined here - --> $DIR/empty-match.rs:26:7 + --> $DIR/empty-match.rs:24:7 | LL | union NonEmptyUnion2 { | ^^^^^^^^^^^^^^ @@ -260,13 +260,13 @@ LL + NonEmptyUnion2 { .. } => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered - --> $DIR/empty-match.rs:154:24 + --> $DIR/empty-match.rs:152:24 | LL | match_guarded_arm!(NonEmptyEnum1::Foo(true)); | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered | note: `NonEmptyEnum1` defined here - --> $DIR/empty-match.rs:33:5 + --> $DIR/empty-match.rs:31:5 | LL | enum NonEmptyEnum1 { | ------------- @@ -281,13 +281,13 @@ LL + NonEmptyEnum1::Foo(_) => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered - --> $DIR/empty-match.rs:159:24 + --> $DIR/empty-match.rs:157:24 | LL | match_guarded_arm!(NonEmptyEnum2::Foo(true)); | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered | note: `NonEmptyEnum2` defined here - --> $DIR/empty-match.rs:40:5 + --> $DIR/empty-match.rs:38:5 | LL | enum NonEmptyEnum2 { | ------------- @@ -305,13 +305,13 @@ LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!() | error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered - --> $DIR/empty-match.rs:164:24 + --> $DIR/empty-match.rs:162:24 | LL | match_guarded_arm!(NonEmptyEnum5::V1); | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered | note: `NonEmptyEnum5` defined here - --> $DIR/empty-match.rs:49:6 + --> $DIR/empty-match.rs:47:6 | LL | enum NonEmptyEnum5 { | ^^^^^^^^^^^^^ diff --git a/tests/ui/pattern/usefulness/match-privately-empty.rs b/tests/ui/pattern/usefulness/match-privately-empty.rs index 315eb03d16564..7b11907ec6dac 100644 --- a/tests/ui/pattern/usefulness/match-privately-empty.rs +++ b/tests/ui/pattern/usefulness/match-privately-empty.rs @@ -1,5 +1,4 @@ #![feature(never_type)] -#![feature(exhaustive_patterns)] mod private { pub struct Private { diff --git a/tests/ui/pattern/usefulness/match-privately-empty.stderr b/tests/ui/pattern/usefulness/match-privately-empty.stderr index 45352f09417f0..9b0523c9f275e 100644 --- a/tests/ui/pattern/usefulness/match-privately-empty.stderr +++ b/tests/ui/pattern/usefulness/match-privately-empty.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered - --> $DIR/match-privately-empty.rs:13:11 + --> $DIR/match-privately-empty.rs:12:11 | LL | match private::DATA { | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered diff --git a/tests/ui/pattern/usefulness/uninhabited.rs b/tests/ui/pattern/usefulness/uninhabited.rs index 5622808d4c7d6..4d482d3cde5b5 100644 --- a/tests/ui/pattern/usefulness/uninhabited.rs +++ b/tests/ui/pattern/usefulness/uninhabited.rs @@ -5,7 +5,6 @@ // `Ty::is_inhabited_from` function. #![feature(never_type)] #![feature(never_type_fallback)] -#![feature(exhaustive_patterns)] #![deny(unreachable_patterns)] macro_rules! assert_empty { diff --git a/tests/ui/reachable/unreachable-loop-patterns.rs b/tests/ui/reachable/unreachable-loop-patterns.rs index e9cef5f47d4aa..4e501353d46b0 100644 --- a/tests/ui/reachable/unreachable-loop-patterns.rs +++ b/tests/ui/reachable/unreachable-loop-patterns.rs @@ -1,5 +1,4 @@ #![feature(never_type, never_type_fallback)] -#![feature(exhaustive_patterns)] #![allow(unreachable_code)] #![deny(unreachable_patterns)] diff --git a/tests/ui/reachable/unreachable-loop-patterns.stderr b/tests/ui/reachable/unreachable-loop-patterns.stderr index 80ffa5d73f034..135f50030f5f7 100644 --- a/tests/ui/reachable/unreachable-loop-patterns.stderr +++ b/tests/ui/reachable/unreachable-loop-patterns.stderr @@ -1,11 +1,11 @@ error: unreachable pattern - --> $DIR/unreachable-loop-patterns.rs:18:9 + --> $DIR/unreachable-loop-patterns.rs:17:9 | LL | for _ in unimplemented!() as Void {} | ^ | note: the lint level is defined here - --> $DIR/unreachable-loop-patterns.rs:5:9 + --> $DIR/unreachable-loop-patterns.rs:4:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/reachable/unreachable-try-pattern.rs b/tests/ui/reachable/unreachable-try-pattern.rs index 23360e73f4a3a..8ebc2a77695be 100644 --- a/tests/ui/reachable/unreachable-try-pattern.rs +++ b/tests/ui/reachable/unreachable-try-pattern.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(never_type, exhaustive_patterns)] +#![feature(never_type)] #![warn(unreachable_code)] #![warn(unreachable_patterns)] diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs index 8f090fe886a00..163f60cc5f6ad 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs @@ -1,3 +1,5 @@ +// check-pass + #![feature(never_type)] #[non_exhaustive] @@ -27,25 +29,22 @@ pub struct IndirectUninhabitedVariants(UninhabitedVariants); struct A; -// This test checks that an empty match on a non-exhaustive uninhabited type through a level of -// indirection from the defining crate will not compile without `#![feature(exhaustive_patterns)]`. - fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( x: IndirectUninhabitedVariants, ) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn main() {} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr deleted file mode 100644 index c121905414035..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr +++ /dev/null @@ -1,79 +0,0 @@ -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty - --> $DIR/indirect_match_same_crate.rs:34:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedEnum` defined here - --> $DIR/indirect_match_same_crate.rs:20:12 - | -LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum); - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedEnum` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty - --> $DIR/indirect_match_same_crate.rs:38:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedStruct` defined here - --> $DIR/indirect_match_same_crate.rs:22:12 - | -LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty - --> $DIR/indirect_match_same_crate.rs:42:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedTupleStruct` defined here - --> $DIR/indirect_match_same_crate.rs:24:12 - | -LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedTupleStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty - --> $DIR/indirect_match_same_crate.rs:48:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedVariants` defined here - --> $DIR/indirect_match_same_crate.rs:26:12 - | -LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedVariants` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs deleted file mode 100644 index be86519ecb159..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs +++ /dev/null @@ -1,40 +0,0 @@ -// aux-build:uninhabited.rs -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] - -extern crate uninhabited; - -use uninhabited::{ - IndirectUninhabitedEnum, - IndirectUninhabitedStruct, - IndirectUninhabitedTupleStruct, - IndirectUninhabitedVariants, -}; - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type through a level of -// indirection from an extern crate will not compile. In particular, this enables the -// `exhaustive_patterns` feature as this can change the branch used in the compiler to determine -// this. - -fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( - x: IndirectUninhabitedVariants, -) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr deleted file mode 100644 index ef97c1fa17f39..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr +++ /dev/null @@ -1,79 +0,0 @@ -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty - --> $DIR/indirect_match_with_exhaustive_patterns.rs:23:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedEnum` defined here - --> $DIR/auxiliary/uninhabited.rs:26:1 - | -LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedEnum` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty - --> $DIR/indirect_match_with_exhaustive_patterns.rs:27:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedStruct` defined here - --> $DIR/auxiliary/uninhabited.rs:28:1 - | -LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty - --> $DIR/indirect_match_with_exhaustive_patterns.rs:31:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedTupleStruct` defined here - --> $DIR/auxiliary/uninhabited.rs:30:1 - | -LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedTupleStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty - --> $DIR/indirect_match_with_exhaustive_patterns.rs:37:11 - | -LL | match x {} - | ^ - | -note: `IndirectUninhabitedVariants` defined here - --> $DIR/auxiliary/uninhabited.rs:32:1 - | -LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `IndirectUninhabitedVariants` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs deleted file mode 100644 index 60289aa780378..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs +++ /dev/null @@ -1,57 +0,0 @@ -// check-pass - -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -#[non_exhaustive] -pub struct UninhabitedStruct { - _priv: !, -} - -#[non_exhaustive] -pub struct UninhabitedTupleStruct(!); - -pub enum UninhabitedVariants { - #[non_exhaustive] Tuple(!), - #[non_exhaustive] Struct { x: ! } -} - -pub struct IndirectUninhabitedEnum(UninhabitedEnum); - -pub struct IndirectUninhabitedStruct(UninhabitedStruct); - -pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); - -pub struct IndirectUninhabitedVariants(UninhabitedVariants); - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate -// will compile. In particular, this enables the `exhaustive_patterns` feature as this can -// change the branch used in the compiler to determine this. -// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. - -fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { - match x {} -} - -fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { - match x {} -} - -fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { - match x {} -} - -fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( - x: IndirectUninhabitedVariants, -) -> A { - match x {} -} - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs index ebbdfba15f3a3..a46e240b0de0a 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -1,3 +1,5 @@ +// check-pass + #![feature(never_type)] #[non_exhaustive] @@ -27,15 +29,15 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { } fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { - match x {} //~ ERROR non-exhaustive patterns + match x {} } fn main() {} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr deleted file mode 100644 index ec2a2f6f05531..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr +++ /dev/null @@ -1,64 +0,0 @@ -error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty - --> $DIR/match_same_crate.rs:30:11 - | -LL | match x {} - | ^ - | -note: `UninhabitedStruct` defined here - --> $DIR/match_same_crate.rs:8:12 - | -LL | pub struct UninhabitedStruct { - | ^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `UninhabitedStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty - --> $DIR/match_same_crate.rs:34:11 - | -LL | match x {} - | ^ - | -note: `UninhabitedTupleStruct` defined here - --> $DIR/match_same_crate.rs:13:12 - | -LL | pub struct UninhabitedTupleStruct(!); - | ^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `UninhabitedTupleStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered - --> $DIR/match_same_crate.rs:38:11 - | -LL | match x {} - | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered - | -note: `UninhabitedVariants` defined here - --> $DIR/match_same_crate.rs:16:23 - | -LL | pub enum UninhabitedVariants { - | ------------------- -LL | #[non_exhaustive] Tuple(!), - | ^^^^^ not covered -LL | #[non_exhaustive] Struct { x: ! } - | ^^^^^^ not covered - = note: the matched value is of type `UninhabitedVariants` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms - | -LL ~ match x { -LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(), -LL ~ } - | - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs deleted file mode 100644 index 900dfff652ea6..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs +++ /dev/null @@ -1,37 +0,0 @@ -// aux-build:uninhabited.rs -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] - -extern crate uninhabited; - -use uninhabited::{ - UninhabitedEnum, - UninhabitedStruct, - UninhabitedTupleStruct, - UninhabitedVariants, -}; - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate -// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can -// change the branch used in the compiler to determine this. - -fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr deleted file mode 100644 index b6b777ec56c43..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr +++ /dev/null @@ -1,83 +0,0 @@ -error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty - --> $DIR/match_with_exhaustive_patterns.rs:22:11 - | -LL | match x {} - | ^ - | -note: `UninhabitedEnum` defined here - --> $DIR/auxiliary/uninhabited.rs:5:1 - | -LL | pub enum UninhabitedEnum { - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty - --> $DIR/match_with_exhaustive_patterns.rs:26:11 - | -LL | match x {} - | ^ - | -note: `UninhabitedStruct` defined here - --> $DIR/auxiliary/uninhabited.rs:9:1 - | -LL | pub struct UninhabitedStruct { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `UninhabitedStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty - --> $DIR/match_with_exhaustive_patterns.rs:30:11 - | -LL | match x {} - | ^ - | -note: `UninhabitedTupleStruct` defined here - --> $DIR/auxiliary/uninhabited.rs:14:1 - | -LL | pub struct UninhabitedTupleStruct(!); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the matched value is of type `UninhabitedTupleStruct` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered - --> $DIR/match_with_exhaustive_patterns.rs:34:11 - | -LL | match x {} - | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered - | -note: `UninhabitedVariants` defined here - --> $DIR/auxiliary/uninhabited.rs:17:23 - | -LL | pub enum UninhabitedVariants { - | ---------------------------- -LL | #[non_exhaustive] Tuple(!), - | ^^^^^ not covered -LL | #[non_exhaustive] Struct { x: ! } - | ^^^^^^ not covered - = note: the matched value is of type `UninhabitedVariants` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms - | -LL ~ match x { -LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(), -LL ~ } - | - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs deleted file mode 100644 index de5530485f3e6..0000000000000 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs +++ /dev/null @@ -1,47 +0,0 @@ -// check-pass - -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -#[non_exhaustive] -pub struct UninhabitedStruct { - _priv: !, -} - -#[non_exhaustive] -pub struct UninhabitedTupleStruct(!); - -pub enum UninhabitedVariants { - #[non_exhaustive] Tuple(!), - #[non_exhaustive] Struct { x: ! } -} - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate -// will compile. In particular, this enables the `exhaustive_patterns` feature as this can -// change the branch used in the compiler to determine this. -// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. - -fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { - match x {} -} - -fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { - match x {} -} - -fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - match x {} -} - -fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { - match x {} -} - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs index 221b5cf6bfad8..f2f349b1b35d2 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs @@ -1,7 +1,6 @@ // aux-build:uninhabited.rs -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] extern crate uninhabited; diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs index ffc496a975ecf..1194d7b858d60 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs @@ -1,5 +1,4 @@ #![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] #![feature(never_type)] #[non_exhaustive] diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr index 8bfd6e91f4dec..9443778058c88 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr @@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:52:9 + --> $DIR/patterns_same_crate.rs:51:9 | LL | Some(_x) => (), | ^^^^^^^^ @@ -11,25 +11,25 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:57:9 + --> $DIR/patterns_same_crate.rs:56:9 | LL | Some(_x) => (), | ^^^^^^^^ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:61:15 + --> $DIR/patterns_same_crate.rs:60:15 | LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:65:15 + --> $DIR/patterns_same_crate.rs:64:15 | LL | while let Some(_x) = uninhabited_struct() { | ^^^^^^^^ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:68:15 + --> $DIR/patterns_same_crate.rs:67:15 | LL | while let Some(_x) = uninhabited_tuple_struct() { | ^^^^^^^^ diff --git a/tests/ui/try-trait/try-operator-custom.rs b/tests/ui/try-trait/try-operator-custom.rs index 45636a7fceddf..8713955f7bdbd 100644 --- a/tests/ui/try-trait/try-operator-custom.rs +++ b/tests/ui/try-trait/try-operator-custom.rs @@ -2,6 +2,7 @@ #![feature(control_flow_enum)] #![feature(try_trait_v2)] +#![allow(unreachable_patterns)] use std::ops::{ControlFlow, FromResidual, Try}; diff --git a/tests/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs b/tests/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs index b59432078350e..3ba6ecf11ef32 100644 --- a/tests/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs +++ b/tests/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(exhaustive_patterns)] - enum Void {} fn main() { let a: Option = None; diff --git a/tests/ui/uninhabited/projection.rs b/tests/ui/uninhabited/projection.rs index be0d3ff7da78f..a78421f739deb 100644 --- a/tests/ui/uninhabited/projection.rs +++ b/tests/ui/uninhabited/projection.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(never_type, exhaustive_patterns)] +#![feature(never_type)] trait Tag { type TagType; diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.rs b/tests/ui/uninhabited/uninhabited-irrefutable.rs index cfd60a8d903fa..809f365d0d608 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.rs +++ b/tests/ui/uninhabited/uninhabited-irrefutable.rs @@ -1,5 +1,4 @@ #![feature(never_type)] -#![feature(exhaustive_patterns)] mod foo { pub struct SecretlyEmpty { diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.stderr index daf75f51b5a11..2fd5e6138751b 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/uninhabited-irrefutable.rs:29:9 + --> $DIR/uninhabited-irrefutable.rs:28:9 | LL | let Foo::D(_y, _z) = x; | ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered @@ -7,7 +7,7 @@ LL | let Foo::D(_y, _z) = x; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html note: `Foo` defined here - --> $DIR/uninhabited-irrefutable.rs:18:6 + --> $DIR/uninhabited-irrefutable.rs:17:6 | LL | enum Foo { | ^^^ diff --git a/tests/ui/uninhabited/uninhabited-matches-feature-gated.rs b/tests/ui/uninhabited/uninhabited-matches-feature-gated.rs deleted file mode 100644 index e804afcf9ed99..0000000000000 --- a/tests/ui/uninhabited/uninhabited-matches-feature-gated.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::mem::zeroed; -enum Void {} - -fn main() { - let x: Result = Ok(23); - let _ = match x { //~ ERROR non-exhaustive - Ok(n) => n, - }; - - // This is pretty much instant UB. However, we have no choice -- we need to - // test matching on a reference to `&Void`; we cannot do anything other than - // just accept the fact that this is UB if `main` did run, but it doesn't; - // this test only checks that these are feature-gated. - let x: &Void = unsafe { zeroed() }; - let _ = match x {}; //~ ERROR non-exhaustive - - let x: (Void,) = unsafe { zeroed() }; - let _ = match x {}; //~ ERROR non-exhaustive - - let x: [Void; 1] = unsafe { zeroed() }; - let _ = match x {}; //~ ERROR non-exhaustive - - let x: &[Void] = unsafe { zeroed() }; - let _ = match x { //~ ERROR non-exhaustive - &[] => (), - }; - - let x: Void = unsafe { zeroed() }; - let _ = match x {}; // okay - - let x: Result = Ok(23); - let _ = match x { //~ ERROR non-exhaustive - Ok(x) => x, - }; - - let x: Result = Ok(23); - let Ok(x) = x; - //~^ ERROR refutable -} diff --git a/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr deleted file mode 100644 index 466d7f2eadb92..0000000000000 --- a/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ /dev/null @@ -1,115 +0,0 @@ -error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:6:19 - | -LL | let _ = match x { - | ^ pattern `Err(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Ok(n) => n, -LL ~ Err(_) => todo!(), - | - -error[E0004]: non-exhaustive patterns: type `&Void` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:15:19 - | -LL | let _ = match x {}; - | ^ - | -note: `Void` defined here - --> $DIR/uninhabited-matches-feature-gated.rs:2:6 - | -LL | enum Void {} - | ^^^^ - = note: the matched value is of type `&Void` - = note: references are always considered inhabited -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ let _ = match x { -LL + _ => todo!(), -LL ~ }; - | - -error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:18:19 - | -LL | let _ = match x {}; - | ^ - | - = note: the matched value is of type `(Void,)` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ let _ = match x { -LL + _ => todo!(), -LL ~ }; - | - -error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:21:19 - | -LL | let _ = match x {}; - | ^ - | - = note: the matched value is of type `[Void; 1]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ let _ = match x { -LL + _ => todo!(), -LL ~ }; - | - -error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:24:19 - | -LL | let _ = match x { - | ^ pattern `&[_, ..]` not covered - | - = note: the matched value is of type `&[Void]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ &[] => (), -LL ~ &[_, ..] => todo!(), - | - -error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:32:19 - | -LL | let _ = match x { - | ^ pattern `Err(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Ok(x) => x, -LL ~ Err(_) => todo!(), - | - -error[E0005]: refutable pattern in local binding - --> $DIR/uninhabited-matches-feature-gated.rs:37:9 - | -LL | let Ok(x) = x; - | ^^^^^ pattern `Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html - = note: the matched value is of type `Result` -help: you might want to use `let else` to handle the variant that isn't matched - | -LL | let Ok(x) = x else { todo!() }; - | ++++++++++++++++ - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0004, E0005. -For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/uninhabited/uninhabited-patterns.rs b/tests/ui/uninhabited/uninhabited-patterns.rs index f1573b6adf0ce..f05534b6075bb 100644 --- a/tests/ui/uninhabited/uninhabited-patterns.rs +++ b/tests/ui/uninhabited/uninhabited-patterns.rs @@ -1,7 +1,5 @@ #![feature(box_patterns)] #![feature(never_type)] -#![feature(exhaustive_patterns)] - #![deny(unreachable_patterns)] diff --git a/tests/ui/uninhabited/uninhabited-patterns.stderr b/tests/ui/uninhabited/uninhabited-patterns.stderr index 655569ad6e086..19f34a52bdbe5 100644 --- a/tests/ui/uninhabited/uninhabited-patterns.stderr +++ b/tests/ui/uninhabited/uninhabited-patterns.stderr @@ -1,35 +1,35 @@ error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:27:9 + --> $DIR/uninhabited-patterns.rs:25:9 | LL | &[..] => (), | ^^^^^ | note: the lint level is defined here - --> $DIR/uninhabited-patterns.rs:6:9 + --> $DIR/uninhabited-patterns.rs:4:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:32:9 + --> $DIR/uninhabited-patterns.rs:30:9 | LL | Ok(box _) => (), | ^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:34:9 + --> $DIR/uninhabited-patterns.rs:32:9 | LL | Err(&[..]) => (), | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:41:9 + --> $DIR/uninhabited-patterns.rs:39:9 | LL | Err(Ok(_y)) => (), | ^^^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:44:15 + --> $DIR/uninhabited-patterns.rs:42:15 | LL | while let Some(_y) = foo() { | ^^^^^^^^