diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 7d361a9ab2bb6..e603ac566f4ec 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -585,6 +585,7 @@ pub enum E2 { V4, } +#[allow(unreachable_patterns)] fn check_niche_behavior() { if let E1::V2 { .. } = (E1::V1 { f: true }) { intrinsics::abort(); diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs index 5a7ddc4cd7fa5..9f096e9022012 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs @@ -430,6 +430,7 @@ pub enum E2 { V4, } +#[allow(unreachable_patterns)] fn check_niche_behavior () { if let E1::V2 { .. } = (E1::V1 { f: true }) { intrinsics::abort(); diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 3e22786a01f7a..9e3bc3e60b12f 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -66,6 +66,7 @@ macro_rules! into_diag_arg_for_number { impl IntoDiagArg for $ty { fn into_diag_arg(self) -> DiagArgValue { // Convert to a string if it won't fit into `Number`. + #[allow(irrefutable_let_patterns)] if let Ok(n) = TryInto::::try_into(self) { DiagArgValue::Number(n) } else { diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index e42a655531b5d..44286cfeeefaa 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -267,6 +267,8 @@ declare_features! ( (accepted, min_const_generics, "1.51.0", Some(74878)), /// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions. (accepted, min_const_unsafe_fn, "1.33.0", Some(55607)), + /// Allows exhaustive pattern matching on uninhabited types when matched by value. + (accepted, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(119612)), /// Allows using `Self` and associated types in struct expressions and patterns. (accepted, more_struct_aliases, "1.16.0", Some(37544)), /// Allows using the MOVBE target feature. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 88a4b5a838246..47810bc9165ef 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -519,9 +519,6 @@ declare_features! ( (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)), /// Allows `#[marker]` on certain traits allowing overlapping implementations. (unstable, marker_trait_attr, "1.30.0", Some(29864)), - /// Allows exhaustive pattern matching on types that contain uninhabited types in cases that are - /// unambiguously sound. - (unstable, min_exhaustive_patterns, "1.77.0", Some(119612)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization /// are fixed. diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index b499604df87e8..5bd7736a3f3cc 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -28,6 +28,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] @@ -48,7 +49,6 @@ #![feature(iter_from_coroutine)] #![feature(let_chains)] #![feature(macro_metavar_expr)] -#![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs index 95fec154918a5..ab2bfcbca3aa6 100644 --- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs @@ -208,14 +208,11 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> { subpairs = cx.field_match_pairs(downcast_place, subpatterns); let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { - i == variant_index || { - (cx.tcx.features().exhaustive_patterns - || cx.tcx.features().min_exhaustive_patterns) - && !v - .inhabited_predicate(cx.tcx, adt_def) - .instantiate(cx.tcx, args) - .apply_ignore_module(cx.tcx, cx.param_env) - } + i == variant_index + || !v + .inhabited_predicate(cx.tcx, adt_def) + .instantiate(cx.tcx, args) + .apply_ignore_module(cx.tcx, cx.param_env) }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); if irrefutable { 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 64c6ff952c686..efaa75800fca4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -695,9 +695,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 (self.tcx.features().exhaustive_patterns - || self.tcx.features().min_exhaustive_patterns) - && let Some(witness_1) = witnesses.get(0) + let witness_1_is_privately_uninhabited = if let Some(witness_1) = witnesses.get(0) && let ty::Adt(adt, args) = witness_1.ty().kind() && adt.is_enum() && let Constructor::Variant(variant_index) = witness_1.ctor() @@ -1059,7 +1057,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( err.note("`&str` cannot be matched exhaustively, so a wildcard `_` is necessary"); } else if cx.is_foreign_non_exhaustive_enum(ty) { err.note(format!("`{ty}` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively")); - } else if cx.is_uninhabited(ty.inner()) && cx.tcx.features().min_exhaustive_patterns { + } else if cx.is_uninhabited(ty.inner()) { // The type is uninhabited yet there is a witness: we must be in the `MaybeInvalid` // case. err.note(format!("`{ty}` is uninhabited but is not being matched by value, so a wildcard `_` is required")); diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index a5c0b13c90be1..e37fa072b6d65 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -54,7 +54,6 @@ pub trait PatCx: Sized + fmt::Debug { type PatData: Clone; fn is_exhaustive_patterns_feature_on(&self) -> bool; - fn is_min_exhaustive_patterns_feature_on(&self) -> bool; /// The number of fields for this constructor. fn ctor_arity(&self, ctor: &Constructor, ty: &Self::Ty) -> usize; diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 6290aeb252312..25f7cc17c11ff 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -237,9 +237,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| { let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); - let is_uninhabited = (cx.tcx.features().exhaustive_patterns - || cx.tcx.features().min_exhaustive_patterns) - && cx.is_uninhabited(*ty); + let is_uninhabited = cx.is_uninhabited(*ty); let skip = is_uninhabited && (!is_visible || is_non_exhaustive); (ty, PrivateUninhabitedField(skip)) }); @@ -925,9 +923,6 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { fn is_exhaustive_patterns_feature_on(&self) -> bool { self.tcx.features().exhaustive_patterns } - fn is_min_exhaustive_patterns_feature_on(&self) -> bool { - self.tcx.features().min_exhaustive_patterns - } fn ctor_arity(&self, ctor: &crate::constructor::Constructor, ty: &Self::Ty) -> usize { self.ctor_arity(ctor, *ty) diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 9710c9e1303dd..6535afcc39862 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -543,13 +543,11 @@ //! recurse into subpatterns. That second part is done through [`PlaceValidity`], most notably //! [`PlaceValidity::specialize`]. //! -//! Having said all that, in practice we don't fully follow what's been presented in this section. -//! Let's call "toplevel exception" the case where the match scrutinee itself has type `!` or -//! `EmptyEnum`. First, on stable rust, we require `_` patterns for empty types in all cases apart -//! from the toplevel exception. The `exhaustive_patterns` and `min_exaustive_patterns` allow -//! omitting patterns in the cases described above. There's a final detail: in the toplevel -//! exception or with the `exhaustive_patterns` feature, we ignore place validity when checking -//! whether a pattern is required for exhaustiveness. I (Nadrieril) hope to deprecate this behavior. +//! Having said all that, we don't fully follow what's been presented in this section. For +//! backwards-compatibility, we ignore place validity when checking whether a pattern is required +//! for exhaustiveness in two cases: when the `exhaustive_patterns` feature gate is on, or when the +//! match scrutinee itself has type `!` or `EmptyEnum`. I (Nadrieril) hope to deprecate this +//! exception. //! //! //! @@ -953,13 +951,10 @@ impl PlaceInfo { self.is_scrutinee && matches!(ctors_for_ty, ConstructorSet::NoConstructors); // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`). - let empty_arms_are_unreachable = self.validity.is_known_valid() - && (is_toplevel_exception - || cx.is_exhaustive_patterns_feature_on() - || cx.is_min_exhaustive_patterns_feature_on()); + let empty_arms_are_unreachable = self.validity.is_known_valid(); // Whether empty patterns can be omitted for exhaustiveness. We ignore place validity in the // toplevel exception and `exhaustive_patterns` cases for backwards compatibility. - let can_omit_empty_arms = empty_arms_are_unreachable + let can_omit_empty_arms = self.validity.is_known_valid() || is_toplevel_exception || cx.is_exhaustive_patterns_feature_on(); diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index 01a56eaa78fcc..ec0bcd43ad24d 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -152,10 +152,6 @@ impl PatCx for Cx { false } - fn is_min_exhaustive_patterns_feature_on(&self) -> bool { - true - } - fn ctor_arity(&self, ctor: &Constructor, ty: &Self::Ty) -> usize { ty.sub_tys(ctor).len() } diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index ecc91ab9a310e..b2116c5121695 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -9,12 +9,12 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(min_exhaustive_patterns)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/compiler/rustc_transmute/src/layout/nfa.rs b/compiler/rustc_transmute/src/layout/nfa.rs index 0dd26badc885f..5db5a8f222db0 100644 --- a/compiler/rustc_transmute/src/layout/nfa.rs +++ b/compiler/rustc_transmute/src/layout/nfa.rs @@ -87,6 +87,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/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 16dcf76e73eb8..d37bacc7d359f 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -91,6 +91,7 @@ pub trait TypeFoldable: TypeVisitable { fn fold_with>(self, folder: &mut F) -> Self { match self.try_fold_with(folder) { Ok(t) => t, + #[cfg(bootstrap)] Err(e) => match e {}, } } @@ -115,6 +116,7 @@ pub trait TypeSuperFoldable: TypeFoldable { fn super_fold_with>(self, folder: &mut F) -> Self { match self.try_super_fold_with(folder) { Ok(t) => t, + #[cfg(bootstrap)] Err(e) => match e {}, } } diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 2d283dac9a97a..7be3de16b2da7 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -121,6 +121,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 {}, } } @@ -242,6 +243,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 9d4520d4ee813..07daa32afa8a3 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -192,6 +192,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -225,7 +226,6 @@ #![feature(link_llvm_intrinsics)] #![feature(macro_metavar_expr)] #![feature(marker_trait_attr)] -#![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] #![feature(must_not_suspend)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 7fc1bc46fef84..93a74ef739b90 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -272,6 +272,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] @@ -299,7 +300,6 @@ #![feature(link_cfg)] #![feature(linkage)] #![feature(macro_metavar_expr_concat)] -#![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(must_not_suspend)] #![feature(needs_panic_runtime)] diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index af74e4b67c162..28755ae0710ca 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2931,6 +2931,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU moved_before_use, same_ctxt, }, + #[allow(unreachable_patterns)] Some(ControlFlow::Break(_)) => unreachable!("type of node is ControlFlow"), None => ExprUseCtxt { node: Node::Crate(cx.tcx.hir().root_module()), diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed index e840adf0fa34b..163be16ad8be7 100644 --- a/src/tools/clippy/tests/ui/single_match_else.fixed +++ b/src/tools/clippy/tests/ui/single_match_else.fixed @@ -89,7 +89,7 @@ fn main() { // lint here use std::convert::Infallible; - if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { + if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { println!("else block"); return; } diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs index 430c4da20f12a..3f1fd2b31832f 100644 --- a/src/tools/clippy/tests/ui/single_match_else.rs +++ b/src/tools/clippy/tests/ui/single_match_else.rs @@ -98,7 +98,7 @@ fn main() { // lint here use std::convert::Infallible; - match Result::::Ok(1) { + match Result::::Ok(1) { Ok(a) => println!("${:?}", a), Err(_) => { println!("else block"); diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr index f8f88379d6d12..61c348260d05e 100644 --- a/src/tools/clippy/tests/ui/single_match_else.stderr +++ b/src/tools/clippy/tests/ui/single_match_else.stderr @@ -64,7 +64,7 @@ LL + } error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` --> tests/ui/single_match_else.rs:101:5 | -LL | / match Result::::Ok(1) { +LL | / match Result::::Ok(1) { LL | | Ok(a) => println!("${:?}", a), LL | | Err(_) => { LL | | println!("else block"); @@ -75,7 +75,7 @@ LL | | } | help: try | -LL ~ if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { +LL ~ if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { LL + println!("else block"); LL + return; LL + } diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 1173da4697564..d781188cd0c2c 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -463,6 +463,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/tests/pass/async-fn.rs b/src/tools/miri/tests/pass/async-fn.rs index 13400c88c7112..67ec2e26b3068 100644 --- a/src/tools/miri/tests/pass/async-fn.rs +++ b/src/tools/miri/tests/pass/async-fn.rs @@ -59,6 +59,7 @@ async fn hello_world() { } // This example comes from https://github.com/rust-lang/rust/issues/115145 +#[allow(unreachable_patterns)] async fn uninhabited_variant() { async fn unreachable(_: Never) {} diff --git a/src/tools/miri/tests/pass/enums.rs b/src/tools/miri/tests/pass/enums.rs index ac7aafc1bb2e3..1dafef025e958 100644 --- a/src/tools/miri/tests/pass/enums.rs +++ b/src/tools/miri/tests/pass/enums.rs @@ -43,6 +43,7 @@ fn discriminant_overflow() { } } +#[allow(unreachable_patterns)] fn more_discriminant_overflow() { pub enum Infallible {} 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 bd43a62341d17..d76f53818716a 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 @@ -27,6 +27,7 @@ macro_rules! from_bytes { ($ty:tt, $value:expr) => { ($ty::from_le_bytes(match ($value).try_into() { Ok(it) => it, + #[allow(unreachable_patterns)] Err(_) => return Err(MirEvalError::InternalError("mismatched size".into())), })) }; 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 057f553380567..9aa2eeebc1757 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 @@ -1161,6 +1161,7 @@ impl<'ctx> MirLowerCtx<'ctx> { ProjectionElem::OpaqueCast(it) => { ProjectionElem::OpaqueCast(it) } + #[allow(unreachable_patterns)] ProjectionElem::Index(it) => match it {}, }) .collect(), diff --git a/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir index 78356a90743a6..bba4d9c0149a1 100644 --- a/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir @@ -13,17 +13,17 @@ fn opt1(_1: &Result) -> &u32 { bb0: { PlaceMention(_1); - _2 = discriminant((*_1)); - switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; + falseEdge -> [real: bb4, imaginary: bb1]; } bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; + _2 = discriminant((*_1)); + switchInt(move _2) -> [1: bb3, otherwise: bb2]; } bb2: { - falseEdge -> [real: bb4, imaginary: bb3]; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb3: { diff --git a/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir index 979fbb2860dcb..fc0769d6f7dcc 100644 --- a/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir @@ -11,25 +11,10 @@ fn opt2(_1: &Result) -> &u32 { bb0: { PlaceMention(_1); - _2 = discriminant((*_1)); - switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } - - bb2: { StorageLive(_3); _3 = &(((*_1) as Ok).0: u32); _0 = &(*_3); StorageDead(_3); return; } - - bb3: { - FakeRead(ForMatchedPlace(None), (((*_1) as Err).0: Void)); - unreachable; - } } diff --git a/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir index 93ebe600b3ff7..86347db4d92eb 100644 --- a/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir @@ -12,24 +12,19 @@ fn opt3(_1: &Result) -> &u32 { bb0: { PlaceMention(_1); _2 = discriminant((*_1)); - switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1]; + switchInt(move _2) -> [1: bb2, otherwise: bb1]; } bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } - - bb2: { - FakeRead(ForMatchedPlace(None), (((*_1) as Err).0: Void)); - unreachable; - } - - bb3: { StorageLive(_3); _3 = &(((*_1) as Ok).0: u32); _0 = &(*_3); StorageDead(_3); return; } + + bb2: { + FakeRead(ForMatchedPlace(None), (((*_1) as Err).0: Void)); + unreachable; + } } diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff index da7a2bd10e01a..1e1ddfae0eb9e 100644 --- a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff +++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff @@ -19,14 +19,16 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb2]; -+ _5 = Eq(_2, const 0_isize); +- switchInt(move _2) -> [1: bb3, otherwise: bb2]; ++ _5 = Ne(_2, const 1_isize); + assume(move _5); -+ goto -> bb4; ++ goto -> bb2; } bb2: { - unreachable; + _0 = const (); + StorageDead(_1); + return; } bb3: { @@ -35,11 +37,5 @@ - StorageLive(_4); unreachable; } - - bb4: { - _0 = const (); - StorageDead(_1); - return; - } } diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff index a2121fc684f5b..809d24aa15a13 100644 --- a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff +++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff @@ -19,14 +19,16 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb2]; -+ _5 = Eq(_2, const 0_isize); +- switchInt(move _2) -> [1: bb3, otherwise: bb2]; ++ _5 = Ne(_2, const 1_isize); + assume(move _5); -+ goto -> bb4; ++ goto -> bb2; } bb2: { - unreachable; + _0 = const (); + StorageDead(_1); + return; } bb3: { @@ -35,11 +37,5 @@ - StorageLive(_4); unreachable; } - - bb4: { - _0 = const (); - StorageDead(_1); - return; - } } diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs index 881e3542f0ac9..f7f4815ae7ce1 100644 --- a/tests/mir-opt/unreachable.rs +++ b/tests/mir-opt/unreachable.rs @@ -45,18 +45,16 @@ fn as_match() { // CHECK: bb0: { // CHECK: {{_.*}} = empty() // CHECK: bb1: { - // CHECK: [[eq:_.*]] = Eq({{.*}}, const 0_isize); + // CHECK: [[eq:_.*]] = Ne({{.*}}, const 1_isize); // CHECK-NEXT: assume(move [[eq]]); - // CHECK-NEXT: goto -> bb4; + // CHECK-NEXT: goto -> bb2; // CHECK: bb2: { - // CHECK-NEXT: unreachable; + // CHECK: return; // CHECK: bb3: { // CHECK-NEXT: unreachable; - // CHECK: bb4: { - // CHECK: return; match empty() { - None => {} Some(_x) => match _x {}, + None => {} } } diff --git a/tests/mir-opt/unreachable_enum_branching.rs b/tests/mir-opt/unreachable_enum_branching.rs index fac14042b1075..7647f9bf0779a 100644 --- a/tests/mir-opt/unreachable_enum_branching.rs +++ b/tests/mir-opt/unreachable_enum_branching.rs @@ -49,7 +49,7 @@ struct Plop { fn simple() { // CHECK-LABEL: fn simple( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb2, otherwise: [[unreachable]]]; + // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb1, otherwise: [[unreachable]]]; // CHECK: [[unreachable]]: { // CHECK-NEXT: unreachable; match Test1::C { diff --git a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff index 8aef991493672..5c08648fac3bb 100644 --- a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff @@ -14,40 +14,40 @@ StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); -- switchInt(move _3) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb1]; -+ switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1]; +- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; ++ switchInt(move _3) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5]; } bb1: { - unreachable; - } - - bb2: { StorageLive(_5); _5 = const "C"; _1 = &(*_5); StorageDead(_5); - goto -> bb5; + goto -> bb4; } - bb3: { + bb2: { StorageLive(_4); _4 = const "B(Empty)"; _1 = &(*_4); StorageDead(_4); - goto -> bb5; + goto -> bb4; } - bb4: { + bb3: { _1 = const "A(Empty)"; - goto -> bb5; + goto -> bb4; } - bb5: { + bb4: { StorageDead(_2); StorageDead(_1); _0 = const (); return; ++ } ++ ++ bb5: { ++ unreachable; } } diff --git a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff index 8aef991493672..5c08648fac3bb 100644 --- a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff @@ -14,40 +14,40 @@ StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); -- switchInt(move _3) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb1]; -+ switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1]; +- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; ++ switchInt(move _3) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5]; } bb1: { - unreachable; - } - - bb2: { StorageLive(_5); _5 = const "C"; _1 = &(*_5); StorageDead(_5); - goto -> bb5; + goto -> bb4; } - bb3: { + bb2: { StorageLive(_4); _4 = const "B(Empty)"; _1 = &(*_4); StorageDead(_4); - goto -> bb5; + goto -> bb4; } - bb4: { + bb3: { _1 = const "A(Empty)"; - goto -> bb5; + goto -> bb4; } - bb5: { + bb4: { StorageDead(_2); StorageDead(_1); _0 = const (); return; ++ } ++ ++ bb5: { ++ unreachable; } } 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 52ed008137fce..74f37b514e4a4 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs @@ -1,10 +1,9 @@ // Test precise capture of a multi-variant enum (when remaining variants are // visibly uninhabited). -//@ revisions: min_exhaustive_patterns exhaustive_patterns +//@ revisions: normal exhaustive_patterns //@ edition:2021 //@ run-pass #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] -#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))] #![feature(never_type)] pub fn main() { diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.svg b/tests/ui/codemap_tests/huge_multispan_highlight.svg index 7b6dbb17c6f95..12058176dc0f1 100644 --- a/tests/ui/codemap_tests/huge_multispan_highlight.svg +++ b/tests/ui/codemap_tests/huge_multispan_highlight.svg @@ -1,4 +1,4 @@ - +