1
Fork 0

Implement feature gate logic

This commit is contained in:
Nadrieril 2024-01-18 19:22:44 +01:00
parent 886108b9fe
commit 95a14d43d7
7 changed files with 806 additions and 158 deletions

View file

@ -95,6 +95,7 @@ pub trait TypeCx: Sized + fmt::Debug {
type PatData: Clone; type PatData: Clone;
fn is_exhaustive_patterns_feature_on(&self) -> bool; fn is_exhaustive_patterns_feature_on(&self) -> bool;
fn is_min_exhaustive_patterns_feature_on(&self) -> bool;
/// The number of fields for this constructor. /// The number of fields for this constructor.
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize; fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize;

View file

@ -182,7 +182,9 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
// `field.ty()` doesn't normalize after substituting. // `field.ty()` doesn't normalize after substituting.
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty); let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
let is_uninhabited = cx.tcx.features().exhaustive_patterns && cx.is_uninhabited(ty); let is_uninhabited = (cx.tcx.features().exhaustive_patterns
|| cx.tcx.features().min_exhaustive_patterns)
&& cx.is_uninhabited(ty);
if is_uninhabited && (!is_visible || is_non_exhaustive) { if is_uninhabited && (!is_visible || is_non_exhaustive) {
None None
@ -960,6 +962,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
fn is_exhaustive_patterns_feature_on(&self) -> bool { fn is_exhaustive_patterns_feature_on(&self) -> bool {
self.tcx.features().exhaustive_patterns 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<Self>, ty: &Self::Ty) -> usize { fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: &Self::Ty) -> usize {
self.ctor_arity(ctor, *ty) self.ctor_arity(ctor, *ty)

View file

@ -548,11 +548,12 @@
//! [`ValidityConstraint::specialize`]. //! [`ValidityConstraint::specialize`].
//! //!
//! Having said all that, in practice we don't fully follow what's been presented in this section. //! Having said all that, in practice we don't fully follow what's been presented in this section.
//! Under `exhaustive_patterns`, we allow omitting empty arms even in `!known_valid` places, for //! Let's call "toplevel exception" the case where the match scrutinee itself has type `!` or
//! backwards-compatibility until we have a better alternative. Without `exhaustive_patterns`, we //! `EmptyEnum`. First, on stable rust, we require `_` patterns for empty types in all cases apart
//! mostly treat empty types as inhabited, except specifically a non-nested `!` or empty enum. In //! from the toplevel exception. The `exhaustive_patterns` and `min_exaustive_patterns` allow
//! this specific case we also allow the empty match regardless of place validity, for //! omitting patterns in the cases described above. There's a final detail: in the toplevel
//! backwards-compatibility. Hopefully we can eventually deprecate this. //! 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.
//! //!
//! //!
//! //!
@ -1440,10 +1441,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
// We treat match scrutinees of type `!` or `EmptyEnum` differently. // We treat match scrutinees of type `!` or `EmptyEnum` differently.
let is_toplevel_exception = let is_toplevel_exception =
is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors); is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
// Whether empty patterns can be omitted for exhaustiveness. // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on(); // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
// Whether empty patterns are counted as useful or not. let empty_arms_are_unreachable = place_validity.is_known_valid()
let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms; && (is_toplevel_exception
|| mcx.tycx.is_exhaustive_patterns_feature_on()
|| mcx.tycx.is_min_exhaustive_patterns_feature_on());
// 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
|| is_toplevel_exception
|| mcx.tycx.is_exhaustive_patterns_feature_on();
// Analyze the constructors present in this column. // Analyze the constructors present in this column.
let ctors = matrix.heads().map(|p| p.ctor()); let ctors = matrix.heads().map(|p| p.ctor());

View file

@ -1,23 +1,23 @@
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:47:9 --> $DIR/empty-types.rs:50:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/empty-types.rs:13:9 --> $DIR/empty-types.rs:16:9
| |
LL | #![deny(unreachable_patterns)] LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:50:9 --> $DIR/empty-types.rs:53:9
| |
LL | _x => {} LL | _x => {}
| ^^ | ^^
error[E0004]: non-exhaustive patterns: type `&!` is non-empty error[E0004]: non-exhaustive patterns: type `&!` is non-empty
--> $DIR/empty-types.rs:54:11 --> $DIR/empty-types.rs:57:11
| |
LL | match ref_never {} LL | match ref_never {}
| ^^^^^^^^^ | ^^^^^^^^^
@ -32,31 +32,31 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:69:9 --> $DIR/empty-types.rs:72:9
| |
LL | (_, _) => {} LL | (_, _) => {}
| ^^^^^^ | ^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:76:9 --> $DIR/empty-types.rs:79:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:79:9 --> $DIR/empty-types.rs:82:9
| |
LL | (_, _) => {} LL | (_, _) => {}
| ^^^^^^ | ^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:83:9 --> $DIR/empty-types.rs:86:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
--> $DIR/empty-types.rs:87:11 --> $DIR/empty-types.rs:90:11
| |
LL | match res_u32_never {} LL | match res_u32_never {}
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@ -75,19 +75,19 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:95:9 --> $DIR/empty-types.rs:98:9
| |
LL | Err(_) => {} LL | Err(_) => {}
| ^^^^^^ | ^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:100:9 --> $DIR/empty-types.rs:103:9
| |
LL | Err(_) => {} LL | Err(_) => {}
| ^^^^^^ | ^^^^^^
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:97:11 --> $DIR/empty-types.rs:100:11
| |
LL | match res_u32_never { LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
@ -105,7 +105,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
| |
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:104:9 --> $DIR/empty-types.rs:107:9
| |
LL | let Ok(_x) = res_u32_never.as_ref(); LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ pattern `Err(_)` not covered | ^^^^^^ pattern `Err(_)` not covered
@ -119,17 +119,11 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++ | ++++++++++++++++
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:115:9 --> $DIR/empty-types.rs:118:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern
--> $DIR/empty-types.rs:119:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:122:9 --> $DIR/empty-types.rs:122:9
| |
@ -137,79 +131,79 @@ LL | Ok(_) => {}
| ^^^^^ | ^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:123:9 --> $DIR/empty-types.rs:125:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:126:9
| |
LL | Ok(_) => {} LL | Ok(_) => {}
| ^^^^^ | ^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:127:9 --> $DIR/empty-types.rs:126:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:129:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:130:9
| |
LL | Err(_) => {} LL | Err(_) => {}
| ^^^^^^ | ^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:136:13 --> $DIR/empty-types.rs:139:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:139:13 --> $DIR/empty-types.rs:142:13
| |
LL | _ if false => {} LL | _ if false => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:148:13 --> $DIR/empty-types.rs:151:13
| |
LL | Some(_) => {} LL | Some(_) => {}
| ^^^^^^^ | ^^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:152:13 --> $DIR/empty-types.rs:155:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:204:13 --> $DIR/empty-types.rs:207:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:209:13 --> $DIR/empty-types.rs:212:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:214:13 --> $DIR/empty-types.rs:217:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:219:13 --> $DIR/empty-types.rs:222:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:225:13 --> $DIR/empty-types.rs:228:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:284:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
@ -217,23 +211,29 @@ LL | _ => {}
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:287:9 --> $DIR/empty-types.rs:287:9
| |
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:290:9
|
LL | (_, _) => {} LL | (_, _) => {}
| ^^^^^^ | ^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:290:9 --> $DIR/empty-types.rs:293:9
| |
LL | Ok(_) => {} LL | Ok(_) => {}
| ^^^^^ | ^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:291:9 --> $DIR/empty-types.rs:294:9
| |
LL | Err(_) => {} LL | Err(_) => {}
| ^^^^^^ | ^^^^^^
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
--> $DIR/empty-types.rs:323:11 --> $DIR/empty-types.rs:326:11
| |
LL | match slice_never {} LL | match slice_never {}
| ^^^^^^^^^^^ | ^^^^^^^^^^^
@ -247,7 +247,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: `&[]` not covered error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:334:11 --> $DIR/empty-types.rs:337:11
| |
LL | match slice_never { LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered | ^^^^^^^^^^^ pattern `&[]` not covered
@ -260,7 +260,7 @@ LL + &[] => todo!()
| |
error[E0004]: non-exhaustive patterns: `&[]` not covered error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:347:11 --> $DIR/empty-types.rs:350:11
| |
LL | match slice_never { LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered | ^^^^^^^^^^^ pattern `&[]` not covered
@ -274,7 +274,7 @@ LL + &[] => todo!()
| |
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
--> $DIR/empty-types.rs:353:11 --> $DIR/empty-types.rs:356:11
| |
LL | match *slice_never {} LL | match *slice_never {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
@ -288,25 +288,25 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:363:9 --> $DIR/empty-types.rs:366:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:366:9 --> $DIR/empty-types.rs:369:9
| |
LL | [_, _, _] => {} LL | [_, _, _] => {}
| ^^^^^^^^^ | ^^^^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:369:9 --> $DIR/empty-types.rs:372:9
| |
LL | [_, ..] => {} LL | [_, ..] => {}
| ^^^^^^^ | ^^^^^^^
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:383:11 --> $DIR/empty-types.rs:386:11
| |
LL | match array_0_never {} LL | match array_0_never {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -320,13 +320,13 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:390:9 --> $DIR/empty-types.rs:393:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error[E0004]: non-exhaustive patterns: `[]` not covered error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11 --> $DIR/empty-types.rs:395:11
| |
LL | match array_0_never { LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered | ^^^^^^^^^^^^^ pattern `[]` not covered
@ -340,49 +340,49 @@ LL + [] => todo!()
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:411:9 --> $DIR/empty-types.rs:414:9
| |
LL | Some(_) => {} LL | Some(_) => {}
| ^^^^^^^ | ^^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:416:9 --> $DIR/empty-types.rs:419:9
| |
LL | Some(_a) => {} LL | Some(_a) => {}
| ^^^^^^^^ | ^^^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:421:9 --> $DIR/empty-types.rs:424:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:426:9 --> $DIR/empty-types.rs:429:9
| |
LL | _a => {} LL | _a => {}
| ^^ | ^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:598:9 --> $DIR/empty-types.rs:601:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:601:9 --> $DIR/empty-types.rs:604:9
| |
LL | _x => {} LL | _x => {}
| ^^ | ^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:604:9 --> $DIR/empty-types.rs:607:9
| |
LL | _ if false => {} LL | _ if false => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:607:9 --> $DIR/empty-types.rs:610:9
| |
LL | _x if false => {} LL | _x if false => {}
| ^^ | ^^

View file

@ -0,0 +1,630 @@
warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/empty-types.rs:13:35
|
LL | #![cfg_attr(min_exh_pats, feature(min_exhaustive_patterns))]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #119612 <https://github.com/rust-lang/rust/issues/119612> for more information
= note: `#[warn(incomplete_features)]` on by default
error: unreachable pattern
--> $DIR/empty-types.rs:50:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-types.rs:16:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:53:9
|
LL | _x => {}
| ^^
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
--> $DIR/empty-types.rs:57:11
|
LL | match ref_never {}
| ^^^^^^^^^
|
= note: the matched value is of type `&!`
= 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 ~ match ref_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:72:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:79:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:82:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:86:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
--> $DIR/empty-types.rs:90:11
|
LL | match res_u32_never {}
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
note: `Result<u32, !>` 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<u32, !>`
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 ~ match res_u32_never {
LL + Ok(_) => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:98:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:103:9
|
LL | Err(_) => {}
| ^^^^^^
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:100:11
|
LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
|
note: `Result<u32, !>` 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<u32, !>`
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 ~ Err(_) => {},
LL ~ Ok(1_u32..=u32::MAX) => todo!()
|
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:107:9
|
LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ 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<&u32, &!>`
help: you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:111:9
|
LL | let Ok(_x) = &res_u32_never;
| ^^^^^^ 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<u32, !>`
help: you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = &res_u32_never else { todo!() };
| ++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:118:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:122:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:125:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:126:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:129:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:130:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:139:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:142:13
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:151:13
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:155:13
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:164:15
|
LL | match *ref_opt_void {
| ^^^^^^^^^^^^^ pattern `Some(_)` not covered
|
note: `Option<Void>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<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 ~ None => {},
LL + Some(_) => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:207:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:212:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:217:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:222:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:228:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:287:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:290:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:293:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:294:9
|
LL | Err(_) => {}
| ^^^^^^
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:315:11
|
LL | match *x {}
| ^^
|
= note: the matched value is of type `(u32, !)`
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 `(!, !)` is non-empty
--> $DIR/empty-types.rs:317:11
|
LL | match *x {}
| ^^
|
= note: the matched value is of type `(!, !)`
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: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:319:11
|
LL | match *x {}
| ^^ patterns `Ok(_)` and `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
::: $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, a match arm with multiple or-patterns as shown, or multiple match arms
|
LL ~ match *x {
LL + Ok(_) | Err(_) => todo!(),
LL ~ }
|
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
--> $DIR/empty-types.rs:321:11
|
LL | match *x {}
| ^^
|
= note: the matched value is of type `[!; 3]`
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 `&[!]` is non-empty
--> $DIR/empty-types.rs:326:11
|
LL | match slice_never {}
| ^^^^^^^^^^^
|
= note: the matched value is of type `&[!]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match slice_never {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
--> $DIR/empty-types.rs:328:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[_, ..]` not covered
|
= note: the matched value is of type `&[!]`
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: `&[]`, `&[_]` and `&[_, _]` not covered
--> $DIR/empty-types.rs:337:11
|
LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
|
= note: the matched value is of type `&[!]`
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 ~ [_, _, _, ..] => {},
LL + &[] | &[_] | &[_, _] => todo!()
|
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
--> $DIR/empty-types.rs:350:11
|
LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
|
= note: the matched value is of type `&[!]`
= note: match arms with guards don't count towards exhaustivity
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 ~ &[..] if false => {},
LL + &[] | &[_, ..] => todo!()
|
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
--> $DIR/empty-types.rs:356:11
|
LL | match *slice_never {}
| ^^^^^^^^^^^^
|
= note: the matched value is of type `[!]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *slice_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:366:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:369:9
|
LL | [_, _, _] => {}
| ^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:372:9
|
LL | [_, ..] => {}
| ^^^^^^^
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:386:11
|
LL | match array_0_never {}
| ^^^^^^^^^^^^^
|
= note: the matched value is of type `[!; 0]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match array_0_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:393:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:395:11
|
LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered
|
= note: the matched value is of type `[!; 0]`
= note: match arms with guards don't count towards exhaustivity
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 ~ [..] if false => {},
LL + [] => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:414:9
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:419:9
|
LL | Some(_a) => {}
| ^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:424:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:429:9
|
LL | _a => {}
| ^^
error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
--> $DIR/empty-types.rs:449:11
|
LL | match ref_opt_never {
| ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
|
note: `Option<!>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `&Option<!>`
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 ~ &None => {},
LL + &Some(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:490:11
|
LL | match *ref_opt_never {
| ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
|
note: `Option<!>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<!>`
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 ~ None => {},
LL + Some(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:538:11
|
LL | match *ref_res_never {
| ^^^^^^^^^^^^^^ 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(_) => {},
LL + Err(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:549:11
|
LL | match *ref_res_never {
| ^^^^^^^^^^^^^^ 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(_a) => {},
LL + Err(_) => todo!()
|
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:568:11
|
LL | match *ref_tuple_half_never {}
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `(u32, !)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *ref_tuple_half_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:601:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:604:9
|
LL | _x => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:607:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:610:9
|
LL | _x if false => {}
| ^^
error[E0004]: non-exhaustive patterns: `&_` not covered
--> $DIR/empty-types.rs:635:11
|
LL | match ref_never {
| ^^^^^^^^^ pattern `&_` not covered
|
= note: the matched value is of type `&!`
= note: references are always considered inhabited
= note: match arms with guards don't count towards exhaustivity
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 ~ &_a if false => {},
LL + &_ => todo!()
|
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:663:11
|
LL | match *x {
| ^^ pattern `Some(_)` not covered
|
note: `Option<Result<!, !>>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<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 ~ None => {},
LL + Some(_) => todo!()
|
error: aborting due to 63 previous errors; 1 warning emitted
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View file

@ -1,23 +1,23 @@
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:47:9 --> $DIR/empty-types.rs:50:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/empty-types.rs:13:9 --> $DIR/empty-types.rs:16:9
| |
LL | #![deny(unreachable_patterns)] LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:50:9 --> $DIR/empty-types.rs:53:9
| |
LL | _x => {} LL | _x => {}
| ^^ | ^^
error[E0004]: non-exhaustive patterns: type `&!` is non-empty error[E0004]: non-exhaustive patterns: type `&!` is non-empty
--> $DIR/empty-types.rs:54:11 --> $DIR/empty-types.rs:57:11
| |
LL | match ref_never {} LL | match ref_never {}
| ^^^^^^^^^ | ^^^^^^^^^
@ -32,7 +32,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:66:11 --> $DIR/empty-types.rs:69:11
| |
LL | match tuple_half_never {} LL | match tuple_half_never {}
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
@ -46,7 +46,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
--> $DIR/empty-types.rs:73:11 --> $DIR/empty-types.rs:76:11
| |
LL | match tuple_never {} LL | match tuple_never {}
| ^^^^^^^^^^^ | ^^^^^^^^^^^
@ -60,13 +60,13 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:83:9 --> $DIR/empty-types.rs:86:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:87:11 --> $DIR/empty-types.rs:90:11
| |
LL | match res_u32_never {} LL | match res_u32_never {}
| ^^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered | ^^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
@ -88,7 +88,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:89:11 --> $DIR/empty-types.rs:92:11
| |
LL | match res_u32_never { LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Err(_)` not covered | ^^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -106,7 +106,7 @@ LL + Err(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:97:11 --> $DIR/empty-types.rs:100:11
| |
LL | match res_u32_never { LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
@ -124,7 +124,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
| |
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:102:9 --> $DIR/empty-types.rs:105:9
| |
LL | let Ok(_x) = res_u32_never; LL | let Ok(_x) = res_u32_never;
| ^^^^^^ pattern `Err(_)` not covered | ^^^^^^ pattern `Err(_)` not covered
@ -138,7 +138,7 @@ LL | let Ok(_x) = res_u32_never else { todo!() };
| ++++++++++++++++ | ++++++++++++++++
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:104:9 --> $DIR/empty-types.rs:107:9
| |
LL | let Ok(_x) = res_u32_never.as_ref(); LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ pattern `Err(_)` not covered | ^^^^^^ pattern `Err(_)` not covered
@ -152,7 +152,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++ | ++++++++++++++++
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:108:9 --> $DIR/empty-types.rs:111:9
| |
LL | let Ok(_x) = &res_u32_never; LL | let Ok(_x) = &res_u32_never;
| ^^^^^^ pattern `&Err(_)` not covered | ^^^^^^ pattern `&Err(_)` not covered
@ -166,7 +166,7 @@ LL | let Ok(_x) = &res_u32_never else { todo!() };
| ++++++++++++++++ | ++++++++++++++++
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:112:11 --> $DIR/empty-types.rs:115:11
| |
LL | match result_never {} LL | match result_never {}
| ^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered | ^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
@ -188,7 +188,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:117:11 --> $DIR/empty-types.rs:120:11
| |
LL | match result_never { LL | match result_never {
| ^^^^^^^^^^^^ pattern `Err(_)` not covered | ^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -205,19 +205,19 @@ LL | Ok(_) => {}, Err(_) => todo!()
| +++++++++++++++++++ | +++++++++++++++++++
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:136:13 --> $DIR/empty-types.rs:139:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:139:13 --> $DIR/empty-types.rs:142:13
| |
LL | _ if false => {} LL | _ if false => {}
| ^ | ^
error[E0004]: non-exhaustive patterns: `Some(_)` not covered error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:142:15 --> $DIR/empty-types.rs:145:15
| |
LL | match opt_void { LL | match opt_void {
| ^^^^^^^^ pattern `Some(_)` not covered | ^^^^^^^^ pattern `Some(_)` not covered
@ -235,7 +235,7 @@ LL + Some(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `Some(_)` not covered error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:161:15 --> $DIR/empty-types.rs:164:15
| |
LL | match *ref_opt_void { LL | match *ref_opt_void {
| ^^^^^^^^^^^^^ pattern `Some(_)` not covered | ^^^^^^^^^^^^^ pattern `Some(_)` not covered
@ -253,43 +253,43 @@ LL + Some(_) => todo!()
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:204:13 --> $DIR/empty-types.rs:207:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:209:13 --> $DIR/empty-types.rs:212:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:214:13 --> $DIR/empty-types.rs:217:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:219:13 --> $DIR/empty-types.rs:222:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:225:13 --> $DIR/empty-types.rs:228:13
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:284:9 --> $DIR/empty-types.rs:287:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:312:11 --> $DIR/empty-types.rs:315:11
| |
LL | match *x {} LL | match *x {}
| ^^ | ^^
@ -303,7 +303,7 @@ LL ~ }
| |
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
--> $DIR/empty-types.rs:314:11 --> $DIR/empty-types.rs:317:11
| |
LL | match *x {} LL | match *x {}
| ^^ | ^^
@ -317,7 +317,7 @@ LL ~ }
| |
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:316:11 --> $DIR/empty-types.rs:319:11
| |
LL | match *x {} LL | match *x {}
| ^^ patterns `Ok(_)` and `Err(_)` not covered | ^^ patterns `Ok(_)` and `Err(_)` not covered
@ -339,7 +339,7 @@ LL ~ }
| |
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
--> $DIR/empty-types.rs:318:11 --> $DIR/empty-types.rs:321:11
| |
LL | match *x {} LL | match *x {}
| ^^ | ^^
@ -353,7 +353,7 @@ LL ~ }
| |
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
--> $DIR/empty-types.rs:323:11 --> $DIR/empty-types.rs:326:11
| |
LL | match slice_never {} LL | match slice_never {}
| ^^^^^^^^^^^ | ^^^^^^^^^^^
@ -367,7 +367,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
--> $DIR/empty-types.rs:325:11 --> $DIR/empty-types.rs:328:11
| |
LL | match slice_never { LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[_, ..]` not covered | ^^^^^^^^^^^ pattern `&[_, ..]` not covered
@ -380,7 +380,7 @@ LL + &[_, ..] => todo!()
| |
error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
--> $DIR/empty-types.rs:334:11 --> $DIR/empty-types.rs:337:11
| |
LL | match slice_never { LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered | ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
@ -393,7 +393,7 @@ LL + &[] | &[_] | &[_, _] => todo!()
| |
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
--> $DIR/empty-types.rs:347:11 --> $DIR/empty-types.rs:350:11
| |
LL | match slice_never { LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered | ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
@ -407,7 +407,7 @@ LL + &[] | &[_, ..] => todo!()
| |
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
--> $DIR/empty-types.rs:353:11 --> $DIR/empty-types.rs:356:11
| |
LL | match *slice_never {} LL | match *slice_never {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
@ -421,7 +421,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
--> $DIR/empty-types.rs:360:11 --> $DIR/empty-types.rs:363:11
| |
LL | match array_3_never {} LL | match array_3_never {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -435,7 +435,7 @@ LL + }
| |
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:383:11 --> $DIR/empty-types.rs:386:11
| |
LL | match array_0_never {} LL | match array_0_never {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -449,13 +449,13 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:390:9 --> $DIR/empty-types.rs:393:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error[E0004]: non-exhaustive patterns: `[]` not covered error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11 --> $DIR/empty-types.rs:395:11
| |
LL | match array_0_never { LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered | ^^^^^^^^^^^^^ pattern `[]` not covered
@ -469,7 +469,7 @@ LL + [] => todo!()
| |
error[E0004]: non-exhaustive patterns: `&Some(_)` not covered error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
--> $DIR/empty-types.rs:446:11 --> $DIR/empty-types.rs:449:11
| |
LL | match ref_opt_never { LL | match ref_opt_never {
| ^^^^^^^^^^^^^ pattern `&Some(_)` not covered | ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
@ -487,7 +487,7 @@ LL + &Some(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `Some(_)` not covered error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:487:11 --> $DIR/empty-types.rs:490:11
| |
LL | match *ref_opt_never { LL | match *ref_opt_never {
| ^^^^^^^^^^^^^^ pattern `Some(_)` not covered | ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
@ -505,7 +505,7 @@ LL + Some(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:535:11 --> $DIR/empty-types.rs:538:11
| |
LL | match *ref_res_never { LL | match *ref_res_never {
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -523,7 +523,7 @@ LL + Err(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `Err(_)` not covered error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:546:11 --> $DIR/empty-types.rs:549:11
| |
LL | match *ref_res_never { LL | match *ref_res_never {
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -541,7 +541,7 @@ LL + Err(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:565:11 --> $DIR/empty-types.rs:568:11
| |
LL | match *ref_tuple_half_never {} LL | match *ref_tuple_half_never {}
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
@ -555,31 +555,31 @@ LL + }
| |
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:598:9 --> $DIR/empty-types.rs:601:9
| |
LL | _ => {} LL | _ => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:601:9 --> $DIR/empty-types.rs:604:9
| |
LL | _x => {} LL | _x => {}
| ^^ | ^^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:604:9 --> $DIR/empty-types.rs:607:9
| |
LL | _ if false => {} LL | _ if false => {}
| ^ | ^
error: unreachable pattern error: unreachable pattern
--> $DIR/empty-types.rs:607:9 --> $DIR/empty-types.rs:610:9
| |
LL | _x if false => {} LL | _x if false => {}
| ^^ | ^^
error[E0004]: non-exhaustive patterns: `&_` not covered error[E0004]: non-exhaustive patterns: `&_` not covered
--> $DIR/empty-types.rs:631:11 --> $DIR/empty-types.rs:635:11
| |
LL | match ref_never { LL | match ref_never {
| ^^^^^^^^^ pattern `&_` not covered | ^^^^^^^^^ pattern `&_` not covered
@ -594,7 +594,7 @@ LL + &_ => todo!()
| |
error[E0004]: non-exhaustive patterns: `Some(_)` not covered error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:659:11 --> $DIR/empty-types.rs:663:11
| |
LL | match *x { LL | match *x {
| ^^ pattern `Some(_)` not covered | ^^ pattern `Some(_)` not covered

View file

@ -1,4 +1,5 @@
// revisions: normal exhaustive_patterns // revisions: normal min_exh_pats exhaustive_patterns
// gate-test-min_exhaustive_patterns
// //
// This tests correct handling of empty types in exhaustiveness checking. // This tests correct handling of empty types in exhaustiveness checking.
// //
@ -9,6 +10,8 @@
// This feature is useful to avoid `!` falling back to `()` all the time. // This feature is useful to avoid `!` falling back to `()` all the time.
#![feature(never_type_fallback)] #![feature(never_type_fallback)]
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![cfg_attr(min_exh_pats, feature(min_exhaustive_patterns))]
//[min_exh_pats]~^ WARN the feature `min_exhaustive_patterns` is incomplete
#![allow(dead_code, unreachable_code)] #![allow(dead_code, unreachable_code)]
#![deny(unreachable_patterns)] #![deny(unreachable_patterns)]
@ -66,17 +69,17 @@ fn basic(x: NeverBundle) {
match tuple_half_never {} match tuple_half_never {}
//[normal]~^ ERROR non-empty //[normal]~^ ERROR non-empty
match tuple_half_never { match tuple_half_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern (_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
let tuple_never: (!, !) = x.tuple_never; let tuple_never: (!, !) = x.tuple_never;
match tuple_never {} match tuple_never {}
//[normal]~^ ERROR non-empty //[normal]~^ ERROR non-empty
match tuple_never { match tuple_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match tuple_never { match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern (_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match tuple_never.0 {} match tuple_never.0 {}
match tuple_never.0 { match tuple_never.0 {
@ -92,12 +95,12 @@ fn basic(x: NeverBundle) {
} }
match res_u32_never { match res_u32_never {
Ok(_) => {} Ok(_) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match res_u32_never { match res_u32_never {
//~^ ERROR non-exhaustive //~^ ERROR non-exhaustive
Ok(0) => {} Ok(0) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
let Ok(_x) = res_u32_never; let Ok(_x) = res_u32_never;
//[normal]~^ ERROR refutable //[normal]~^ ERROR refutable
@ -106,25 +109,25 @@ fn basic(x: NeverBundle) {
// Non-obvious difference: here there's an implicit dereference in the patterns, which makes the // Non-obvious difference: here there's an implicit dereference in the patterns, which makes the
// inner place !known_valid. `exhaustive_patterns` ignores this. // inner place !known_valid. `exhaustive_patterns` ignores this.
let Ok(_x) = &res_u32_never; let Ok(_x) = &res_u32_never;
//[normal]~^ ERROR refutable //[normal,min_exh_pats]~^ ERROR refutable
let result_never: Result<!, !> = x.result_never; let result_never: Result<!, !> = x.result_never;
match result_never {} match result_never {}
//[normal]~^ ERROR non-exhaustive //[normal]~^ ERROR non-exhaustive
match result_never { match result_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match result_never { match result_never {
//[normal]~^ ERROR non-exhaustive //[normal]~^ ERROR non-exhaustive
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match result_never { match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match result_never { match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
} }
@ -145,11 +148,11 @@ fn void_same_as_never(x: NeverBundle) {
} }
match opt_void { match opt_void {
None => {} None => {}
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match opt_void { match opt_void {
None => {} None => {}
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
let ref_void: &Void = &x.void; let ref_void: &Void = &x.void;
@ -159,7 +162,7 @@ fn void_same_as_never(x: NeverBundle) {
} }
let ref_opt_void: &Option<Void> = &None; let ref_opt_void: &Option<Void> = &None;
match *ref_opt_void { match *ref_opt_void {
//[normal]~^ ERROR non-exhaustive //[normal,min_exh_pats]~^ ERROR non-exhaustive
None => {} None => {}
} }
match *ref_opt_void { match *ref_opt_void {
@ -284,11 +287,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
_ => {} //~ ERROR unreachable pattern _ => {} //~ ERROR unreachable pattern
} }
match tuple_never { match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern (_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match result_never { match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
// These should be considered !known_valid and not warn unreachable. // These should be considered !known_valid and not warn unreachable.
@ -309,13 +312,13 @@ fn invalid_empty_match(bundle: NeverBundle) {
match *x {} match *x {}
let x: &(u32, !) = &bundle.tuple_half_never; let x: &(u32, !) = &bundle.tuple_half_never;
match *x {} //[normal]~ ERROR non-exhaustive match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
let x: &(!, !) = &bundle.tuple_never; let x: &(!, !) = &bundle.tuple_never;
match *x {} //[normal]~ ERROR non-exhaustive match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
let x: &Result<!, !> = &bundle.result_never; let x: &Result<!, !> = &bundle.result_never;
match *x {} //[normal]~ ERROR non-exhaustive match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
let x: &[!; 3] = &bundle.array_3_never; let x: &[!; 3] = &bundle.array_3_never;
match *x {} //[normal]~ ERROR non-exhaustive match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
} }
fn arrays_and_slices(x: NeverBundle) { fn arrays_and_slices(x: NeverBundle) {
@ -323,7 +326,7 @@ fn arrays_and_slices(x: NeverBundle) {
match slice_never {} match slice_never {}
//~^ ERROR non-empty //~^ ERROR non-empty
match slice_never { match slice_never {
//[normal]~^ ERROR not covered //[normal,min_exh_pats]~^ ERROR not covered
[] => {} [] => {}
} }
match slice_never { match slice_never {
@ -332,7 +335,7 @@ fn arrays_and_slices(x: NeverBundle) {
[_, _, ..] => {} [_, _, ..] => {}
} }
match slice_never { match slice_never {
//[normal]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered //[normal,min_exh_pats]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered //[exhaustive_patterns]~^^ ERROR `&[]` not covered
[_, _, _, ..] => {} [_, _, _, ..] => {}
} }
@ -345,7 +348,7 @@ fn arrays_and_slices(x: NeverBundle) {
_x => {} _x => {}
} }
match slice_never { match slice_never {
//[normal]~^ ERROR `&[]` and `&[_, ..]` not covered //[normal,min_exh_pats]~^ ERROR `&[]` and `&[_, ..]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered //[exhaustive_patterns]~^^ ERROR `&[]` not covered
&[..] if false => {} &[..] if false => {}
} }
@ -360,13 +363,13 @@ fn arrays_and_slices(x: NeverBundle) {
match array_3_never {} match array_3_never {}
//[normal]~^ ERROR non-empty //[normal]~^ ERROR non-empty
match array_3_never { match array_3_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match array_3_never { match array_3_never {
[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern [_, _, _] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match array_3_never { match array_3_never {
[_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern [_, ..] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
let ref_array_3_never: &[!; 3] = &array_3_never; let ref_array_3_never: &[!; 3] = &array_3_never;
@ -408,22 +411,22 @@ fn bindings(x: NeverBundle) {
match opt_never { match opt_never {
None => {} None => {}
// !useful, !reachable // !useful, !reachable
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match opt_never { match opt_never {
None => {} None => {}
// !useful, !reachable // !useful, !reachable
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern Some(_a) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match opt_never { match opt_never {
None => {} None => {}
// !useful, !reachable // !useful, !reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
match opt_never { match opt_never {
None => {} None => {}
// !useful, !reachable // !useful, !reachable
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern _a => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
} }
// The scrutinee is known_valid, but under the `&` isn't anymore. // The scrutinee is known_valid, but under the `&` isn't anymore.
@ -444,7 +447,7 @@ fn bindings(x: NeverBundle) {
&_a => {} &_a => {}
} }
match ref_opt_never { match ref_opt_never {
//[normal]~^ ERROR non-exhaustive //[normal,min_exh_pats]~^ ERROR non-exhaustive
&None => {} &None => {}
} }
match ref_opt_never { match ref_opt_never {
@ -485,7 +488,7 @@ fn bindings(x: NeverBundle) {
ref _a => {} ref _a => {}
} }
match *ref_opt_never { match *ref_opt_never {
//[normal]~^ ERROR non-exhaustive //[normal,min_exh_pats]~^ ERROR non-exhaustive
None => {} None => {}
} }
match *ref_opt_never { match *ref_opt_never {
@ -533,7 +536,7 @@ fn bindings(x: NeverBundle) {
let ref_res_never: &Result<!, !> = &x.result_never; let ref_res_never: &Result<!, !> = &x.result_never;
match *ref_res_never { match *ref_res_never {
//[normal]~^ ERROR non-exhaustive //[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, reachable // useful, reachable
Ok(_) => {} Ok(_) => {}
} }
@ -544,7 +547,7 @@ fn bindings(x: NeverBundle) {
_ => {} _ => {}
} }
match *ref_res_never { match *ref_res_never {
//[normal]~^ ERROR non-exhaustive //[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, !reachable // useful, !reachable
Ok(_a) => {} Ok(_a) => {}
} }
@ -563,7 +566,7 @@ fn bindings(x: NeverBundle) {
let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never; let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never;
match *ref_tuple_half_never {} match *ref_tuple_half_never {}
//[normal]~^ ERROR non-empty //[normal,min_exh_pats]~^ ERROR non-empty
match *ref_tuple_half_never { match *ref_tuple_half_never {
// useful, reachable // useful, reachable
(_, _) => {} (_, _) => {}
@ -614,6 +617,7 @@ fn guards_and_validity(x: NeverBundle) {
// useful, reachable // useful, reachable
_ => {} _ => {}
} }
// Now the madness commences. The guard caused a load of the value thus asserting validity. So // Now the madness commences. The guard caused a load of the value thus asserting validity. So
// there's no invalid value for `_` to catch. So the second pattern is unreachable despite the // there's no invalid value for `_` to catch. So the second pattern is unreachable despite the
// guard not being taken. // guard not being taken.
@ -629,7 +633,7 @@ fn guards_and_validity(x: NeverBundle) {
_a if false => {} _a if false => {}
} }
match ref_never { match ref_never {
//[normal]~^ ERROR non-exhaustive //[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, !reachable // useful, !reachable
&_a if false => {} &_a if false => {}
} }
@ -657,7 +661,7 @@ fn diagnostics_subtlety(x: NeverBundle) {
// Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`. // Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`.
let x: &Option<Result<!, !>> = &None; let x: &Option<Result<!, !>> = &None;
match *x { match *x {
//[normal]~^ ERROR `Some(_)` not covered //[normal,min_exh_pats]~^ ERROR `Some(_)` not covered
None => {} None => {}
} }
} }