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;
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<Self>, ty: &Self::Ty) -> usize;

View File

@ -182,7 +182,9 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
// `field.ty()` doesn't normalize after substituting.
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_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) {
None
@ -960,6 +962,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'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<Self>, ty: &Self::Ty) -> usize {
self.ctor_arity(ctor, *ty)

View File

@ -548,11 +548,12 @@
//! [`ValidityConstraint::specialize`].
//!
//! 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
//! backwards-compatibility until we have a better alternative. Without `exhaustive_patterns`, we
//! mostly treat empty types as inhabited, except specifically a non-nested `!` or empty enum. In
//! this specific case we also allow the empty match regardless of place validity, for
//! backwards-compatibility. Hopefully we can eventually deprecate this.
//! 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.
//!
//!
//!
@ -1440,10 +1441,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
// We treat match scrutinees of type `!` or `EmptyEnum` differently.
let is_toplevel_exception =
is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
// Whether empty patterns can be omitted for exhaustiveness.
let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on();
// Whether empty patterns are counted as useful or not.
let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms;
// 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 = place_validity.is_known_valid()
&& (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.
let ctors = matrix.heads().map(|p| p.ctor());

View File

@ -1,23 +1,23 @@
error: unreachable pattern
--> $DIR/empty-types.rs:47:9
--> $DIR/empty-types.rs:50:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-types.rs:13:9
--> $DIR/empty-types.rs:16:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:50:9
--> $DIR/empty-types.rs:53:9
|
LL | _x => {}
| ^^
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 {}
| ^^^^^^^^^
@ -32,31 +32,31 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:69:9
--> $DIR/empty-types.rs:72:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:76:9
--> $DIR/empty-types.rs:79:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:79:9
--> $DIR/empty-types.rs:82:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:83:9
--> $DIR/empty-types.rs:86:9
|
LL | _ => {}
| ^
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 {}
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@ -75,19 +75,19 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:95:9
--> $DIR/empty-types.rs:98:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:100:9
--> $DIR/empty-types.rs:103:9
|
LL | Err(_) => {}
| ^^^^^^
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 {
| ^^^^^^^^^^^^^ 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
--> $DIR/empty-types.rs:104:9
--> $DIR/empty-types.rs:107:9
|
LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ pattern `Err(_)` not covered
@ -119,17 +119,11 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:115:9
--> $DIR/empty-types.rs:118:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:119:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:122:9
|
@ -137,79 +131,79 @@ LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:123:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:126:9
--> $DIR/empty-types.rs:125:9
|
LL | Ok(_) => {}
| ^^^^^
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(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:136:13
--> $DIR/empty-types.rs:139:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:139:13
--> $DIR/empty-types.rs:142:13
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:148:13
--> $DIR/empty-types.rs:151:13
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:152:13
--> $DIR/empty-types.rs:155:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:204:13
--> $DIR/empty-types.rs:207:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:209:13
--> $DIR/empty-types.rs:212:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:214:13
--> $DIR/empty-types.rs:217:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:219:13
--> $DIR/empty-types.rs:222:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:225:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:284:9
--> $DIR/empty-types.rs:228:13
|
LL | _ => {}
| ^
@ -217,23 +211,29 @@ 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:290:9
--> $DIR/empty-types.rs:293:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:291:9
--> $DIR/empty-types.rs:294:9
|
LL | Err(_) => {}
| ^^^^^^
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 {}
| ^^^^^^^^^^^
@ -247,7 +247,7 @@ LL + }
|
error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:334:11
--> $DIR/empty-types.rs:337:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered
@ -260,7 +260,7 @@ LL + &[] => todo!()
|
error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:347:11
--> $DIR/empty-types.rs:350:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered
@ -274,7 +274,7 @@ LL + &[] => todo!()
|
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 {}
| ^^^^^^^^^^^^
@ -288,25 +288,25 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:363:9
--> $DIR/empty-types.rs:366:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:366:9
--> $DIR/empty-types.rs:369:9
|
LL | [_, _, _] => {}
| ^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:369:9
--> $DIR/empty-types.rs:372:9
|
LL | [_, ..] => {}
| ^^^^^^^
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 {}
| ^^^^^^^^^^^^^
@ -320,13 +320,13 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:390:9
--> $DIR/empty-types.rs:393:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11
--> $DIR/empty-types.rs:395:11
|
LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered
@ -340,49 +340,49 @@ LL + [] => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:411:9
--> $DIR/empty-types.rs:414:9
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:416:9
--> $DIR/empty-types.rs:419:9
|
LL | Some(_a) => {}
| ^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:421:9
--> $DIR/empty-types.rs:424:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:426:9
--> $DIR/empty-types.rs:429:9
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:598:9
--> $DIR/empty-types.rs:601:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:601:9
--> $DIR/empty-types.rs:604:9
|
LL | _x => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:604:9
--> $DIR/empty-types.rs:607:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:607:9
--> $DIR/empty-types.rs:610:9
|
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
--> $DIR/empty-types.rs:47:9
--> $DIR/empty-types.rs:50:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-types.rs:13:9
--> $DIR/empty-types.rs:16:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:50:9
--> $DIR/empty-types.rs:53:9
|
LL | _x => {}
| ^^
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 {}
| ^^^^^^^^^
@ -32,7 +32,7 @@ LL + }
|
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 {}
| ^^^^^^^^^^^^^^^^
@ -46,7 +46,7 @@ LL + }
|
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 {}
| ^^^^^^^^^^^
@ -60,13 +60,13 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:83:9
--> $DIR/empty-types.rs:86:9
|
LL | _ => {}
| ^
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 {}
| ^^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
@ -88,7 +88,7 @@ LL + }
|
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 {
| ^^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -106,7 +106,7 @@ LL + Err(_) => todo!()
|
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 {
| ^^^^^^^^^^^^^ 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
--> $DIR/empty-types.rs:102:9
--> $DIR/empty-types.rs:105:9
|
LL | let Ok(_x) = res_u32_never;
| ^^^^^^ pattern `Err(_)` not covered
@ -138,7 +138,7 @@ LL | let Ok(_x) = res_u32_never else { todo!() };
| ++++++++++++++++
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();
| ^^^^^^ 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
--> $DIR/empty-types.rs:108:9
--> $DIR/empty-types.rs:111:9
|
LL | let Ok(_x) = &res_u32_never;
| ^^^^^^ 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
--> $DIR/empty-types.rs:112:11
--> $DIR/empty-types.rs:115:11
|
LL | match result_never {}
| ^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
@ -188,7 +188,7 @@ LL + }
|
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:117:11
--> $DIR/empty-types.rs:120:11
|
LL | match result_never {
| ^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -205,19 +205,19 @@ LL | Ok(_) => {}, Err(_) => todo!()
| +++++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:136:13
--> $DIR/empty-types.rs:139:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:139:13
--> $DIR/empty-types.rs:142:13
|
LL | _ if false => {}
| ^
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:142:15
--> $DIR/empty-types.rs:145:15
|
LL | match opt_void {
| ^^^^^^^^ pattern `Some(_)` not covered
@ -235,7 +235,7 @@ LL + Some(_) => todo!()
|
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 {
| ^^^^^^^^^^^^^ pattern `Some(_)` not covered
@ -253,43 +253,43 @@ LL + Some(_) => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:204:13
--> $DIR/empty-types.rs:207:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:209:13
--> $DIR/empty-types.rs:212:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:214:13
--> $DIR/empty-types.rs:217:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:219:13
--> $DIR/empty-types.rs:222:13
|
LL | _ => {}
| ^
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
--> $DIR/empty-types.rs:287:9
|
LL | _ => {}
| ^
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 {}
| ^^
@ -303,7 +303,7 @@ LL ~ }
|
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
--> $DIR/empty-types.rs:314:11
--> $DIR/empty-types.rs:317:11
|
LL | match *x {}
| ^^
@ -317,7 +317,7 @@ LL ~ }
|
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 {}
| ^^ patterns `Ok(_)` and `Err(_)` not covered
@ -339,7 +339,7 @@ LL ~ }
|
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 {}
| ^^
@ -353,7 +353,7 @@ LL ~ }
|
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 {}
| ^^^^^^^^^^^
@ -367,7 +367,7 @@ LL + }
|
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
--> $DIR/empty-types.rs:325:11
--> $DIR/empty-types.rs:328:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[_, ..]` not covered
@ -380,7 +380,7 @@ LL + &[_, ..] => todo!()
|
error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
--> $DIR/empty-types.rs:334:11
--> $DIR/empty-types.rs:337:11
|
LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
@ -393,7 +393,7 @@ LL + &[] | &[_] | &[_, _] => todo!()
|
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
--> $DIR/empty-types.rs:347:11
--> $DIR/empty-types.rs:350:11
|
LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
@ -407,7 +407,7 @@ LL + &[] | &[_, ..] => todo!()
|
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 {}
| ^^^^^^^^^^^^
@ -421,7 +421,7 @@ LL + }
|
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 {}
| ^^^^^^^^^^^^^
@ -435,7 +435,7 @@ LL + }
|
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 {}
| ^^^^^^^^^^^^^
@ -449,13 +449,13 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:390:9
--> $DIR/empty-types.rs:393:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11
--> $DIR/empty-types.rs:395:11
|
LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered
@ -469,7 +469,7 @@ LL + [] => todo!()
|
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 {
| ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
@ -487,7 +487,7 @@ LL + &Some(_) => todo!()
|
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 {
| ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
@ -505,7 +505,7 @@ LL + Some(_) => todo!()
|
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 {
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -523,7 +523,7 @@ LL + Err(_) => todo!()
|
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 {
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@ -541,7 +541,7 @@ LL + Err(_) => todo!()
|
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 {}
| ^^^^^^^^^^^^^^^^^^^^^
@ -555,31 +555,31 @@ LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:598:9
--> $DIR/empty-types.rs:601:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:601:9
--> $DIR/empty-types.rs:604:9
|
LL | _x => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:604:9
--> $DIR/empty-types.rs:607:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:607:9
--> $DIR/empty-types.rs:610:9
|
LL | _x if false => {}
| ^^
error[E0004]: non-exhaustive patterns: `&_` not covered
--> $DIR/empty-types.rs:631:11
--> $DIR/empty-types.rs:635:11
|
LL | match ref_never {
| ^^^^^^^^^ pattern `&_` not covered
@ -594,7 +594,7 @@ LL + &_ => todo!()
|
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:659:11
--> $DIR/empty-types.rs:663:11
|
LL | match *x {
| ^^ 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.
//
@ -9,6 +10,8 @@
// This feature is useful to avoid `!` falling back to `()` all the time.
#![feature(never_type_fallback)]
#![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)]
#![deny(unreachable_patterns)]
@ -66,17 +69,17 @@ fn basic(x: NeverBundle) {
match tuple_half_never {}
//[normal]~^ ERROR non-empty
match tuple_half_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
let tuple_never: (!, !) = x.tuple_never;
match tuple_never {}
//[normal]~^ ERROR non-empty
match tuple_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match tuple_never.0 {}
match tuple_never.0 {
@ -92,12 +95,12 @@ fn basic(x: NeverBundle) {
}
match res_u32_never {
Ok(_) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match res_u32_never {
//~^ ERROR non-exhaustive
Ok(0) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
let Ok(_x) = res_u32_never;
//[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
// inner place !known_valid. `exhaustive_patterns` ignores this.
let Ok(_x) = &res_u32_never;
//[normal]~^ ERROR refutable
//[normal,min_exh_pats]~^ ERROR refutable
let result_never: Result<!, !> = x.result_never;
match result_never {}
//[normal]~^ ERROR non-exhaustive
match result_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
//[normal]~^ ERROR non-exhaustive
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ 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 {
None => {}
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_void {
None => {}
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
let ref_void: &Void = &x.void;
@ -159,7 +162,7 @@ fn void_same_as_never(x: NeverBundle) {
}
let ref_opt_void: &Option<Void> = &None;
match *ref_opt_void {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
None => {}
}
match *ref_opt_void {
@ -284,11 +287,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
_ => {} //~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
// These should be considered !known_valid and not warn unreachable.
@ -309,13 +312,13 @@ fn invalid_empty_match(bundle: NeverBundle) {
match *x {}
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;
match *x {} //[normal]~ ERROR non-exhaustive
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
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;
match *x {} //[normal]~ ERROR non-exhaustive
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
}
fn arrays_and_slices(x: NeverBundle) {
@ -323,7 +326,7 @@ fn arrays_and_slices(x: NeverBundle) {
match slice_never {}
//~^ ERROR non-empty
match slice_never {
//[normal]~^ ERROR not covered
//[normal,min_exh_pats]~^ ERROR not covered
[] => {}
}
match slice_never {
@ -332,7 +335,7 @@ fn arrays_and_slices(x: NeverBundle) {
[_, _, ..] => {}
}
match slice_never {
//[normal]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
//[normal,min_exh_pats]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
[_, _, _, ..] => {}
}
@ -345,7 +348,7 @@ fn arrays_and_slices(x: NeverBundle) {
_x => {}
}
match slice_never {
//[normal]~^ ERROR `&[]` and `&[_, ..]` not covered
//[normal,min_exh_pats]~^ ERROR `&[]` and `&[_, ..]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
&[..] if false => {}
}
@ -360,13 +363,13 @@ fn arrays_and_slices(x: NeverBundle) {
match array_3_never {}
//[normal]~^ ERROR non-empty
match array_3_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match array_3_never {
[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
[_, _, _] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
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;
@ -408,22 +411,22 @@ fn bindings(x: NeverBundle) {
match opt_never {
None => {}
// !useful, !reachable
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Some(_a) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !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.
@ -444,7 +447,7 @@ fn bindings(x: NeverBundle) {
&_a => {}
}
match ref_opt_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
&None => {}
}
match ref_opt_never {
@ -485,7 +488,7 @@ fn bindings(x: NeverBundle) {
ref _a => {}
}
match *ref_opt_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
None => {}
}
match *ref_opt_never {
@ -533,7 +536,7 @@ fn bindings(x: NeverBundle) {
let ref_res_never: &Result<!, !> = &x.result_never;
match *ref_res_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, reachable
Ok(_) => {}
}
@ -544,7 +547,7 @@ fn bindings(x: NeverBundle) {
_ => {}
}
match *ref_res_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, !reachable
Ok(_a) => {}
}
@ -563,7 +566,7 @@ fn bindings(x: NeverBundle) {
let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never;
match *ref_tuple_half_never {}
//[normal]~^ ERROR non-empty
//[normal,min_exh_pats]~^ ERROR non-empty
match *ref_tuple_half_never {
// useful, reachable
(_, _) => {}
@ -614,6 +617,7 @@ fn guards_and_validity(x: NeverBundle) {
// useful, reachable
_ => {}
}
// 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
// guard not being taken.
@ -629,7 +633,7 @@ fn guards_and_validity(x: NeverBundle) {
_a if false => {}
}
match ref_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, !reachable
&_a if false => {}
}
@ -657,7 +661,7 @@ fn diagnostics_subtlety(x: NeverBundle) {
// Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`.
let x: &Option<Result<!, !>> = &None;
match *x {
//[normal]~^ ERROR `Some(_)` not covered
//[normal,min_exh_pats]~^ ERROR `Some(_)` not covered
None => {}
}
}