1
Fork 0

Match usize/isize exhaustively

This commit is contained in:
Nadrieril 2023-10-13 00:20:06 +02:00
parent 6f35ae6f9b
commit a4875ae1e2
18 changed files with 321 additions and 307 deletions

View file

@ -703,14 +703,21 @@ fn report_arm_reachability<'p, 'tcx>(
} }
fn collect_non_exhaustive_tys<'tcx>( fn collect_non_exhaustive_tys<'tcx>(
tcx: TyCtxt<'tcx>,
pat: &WitnessPat<'tcx>, pat: &WitnessPat<'tcx>,
non_exhaustive_tys: &mut FxHashSet<Ty<'tcx>>, non_exhaustive_tys: &mut FxHashSet<Ty<'tcx>>,
) { ) {
if matches!(pat.ctor(), Constructor::NonExhaustive) { if matches!(pat.ctor(), Constructor::NonExhaustive) {
non_exhaustive_tys.insert(pat.ty()); non_exhaustive_tys.insert(pat.ty());
} }
if let Constructor::IntRange(range) = pat.ctor() {
if range.is_beyond_boundaries(pat.ty(), tcx) {
// The range denotes the values before `isize::MIN` or the values after `usize::MAX`/`isize::MAX`.
non_exhaustive_tys.insert(pat.ty());
}
}
pat.iter_fields() pat.iter_fields()
.for_each(|field_pat| collect_non_exhaustive_tys(field_pat, non_exhaustive_tys)) .for_each(|field_pat| collect_non_exhaustive_tys(tcx, field_pat, non_exhaustive_tys))
} }
/// Report that a match is not exhaustive. /// Report that a match is not exhaustive.
@ -764,16 +771,24 @@ fn non_exhaustive_match<'p, 'tcx>(
adt_defined_here(cx, &mut err, scrut_ty, &witnesses); adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
err.note(format!("the matched value is of type `{}`", scrut_ty)); err.note(format!("the matched value is of type `{}`", scrut_ty));
if !is_empty_match && witnesses.len() == 1 { if !is_empty_match {
let mut non_exhaustive_tys = FxHashSet::default(); let mut non_exhaustive_tys = FxHashSet::default();
collect_non_exhaustive_tys(&witnesses[0], &mut non_exhaustive_tys); // Look at the first witness.
collect_non_exhaustive_tys(cx.tcx, &witnesses[0], &mut non_exhaustive_tys);
for ty in non_exhaustive_tys { for ty in non_exhaustive_tys {
if ty.is_ptr_sized_integral() { if ty.is_ptr_sized_integral() {
err.note(format!( if ty == cx.tcx.types.usize {
"`{ty}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \ err.note(format!(
exhaustively", "`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
exhaustively",
)); ));
} else if ty == cx.tcx.types.isize {
err.note(format!(
"`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
exhaustively",
));
}
if cx.tcx.sess.is_nightly_build() { if cx.tcx.sess.is_nightly_build() {
err.help(format!( err.help(format!(
"add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \ "add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \

View file

@ -56,6 +56,7 @@ use rustc_hir::RangeEnd;
use rustc_index::Idx; use rustc_index::Idx;
use rustc_middle::middle::stability::EvalResult; use rustc_middle::middle::stability::EvalResult;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary};
use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
@ -139,20 +140,32 @@ impl MaybeInfiniteInt {
PatRangeBoundary::PosInfinity => PosInfinity, PatRangeBoundary::PosInfinity => PosInfinity,
} }
} }
// This could change from finite to infinite if we got `usize::MAX+1` after range splitting.
fn to_pat_range_bdy<'tcx>(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> PatRangeBoundary<'tcx> { fn to_pat_range_bdy<'tcx>(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> PatRangeBoundary<'tcx> {
match self { match self {
NegInfinity => PatRangeBoundary::NegInfinity, NegInfinity => PatRangeBoundary::NegInfinity,
Finite(x) => { Finite(x) => {
let bias = Self::signed_bias(tcx, ty); let bias = Self::signed_bias(tcx, ty);
let bits = x ^ bias; let bits = x ^ bias;
let env = ty::ParamEnv::empty().and(ty); let size = ty.primitive_size(tcx);
let value = mir::Const::from_bits(tcx, bits, env); match Scalar::try_from_uint(bits, size) {
PatRangeBoundary::Finite(value) Some(scalar) => {
let value = mir::Const::from_scalar(tcx, scalar, ty);
PatRangeBoundary::Finite(value)
}
// The value doesn't fit. Since `x >= 0` and 0 always encodes the minimum value
// for a type, the problem isn't that the value is too small. So it must be too
// large.
None => PatRangeBoundary::PosInfinity,
}
} }
JustAfterMax | PosInfinity => PatRangeBoundary::PosInfinity, JustAfterMax | PosInfinity => PatRangeBoundary::PosInfinity,
} }
} }
fn is_finite(self) -> bool {
matches!(self, Finite(_))
}
fn minus_one(self) -> Self { fn minus_one(self) -> Self {
match self { match self {
Finite(n) => match n.checked_sub(1) { Finite(n) => match n.checked_sub(1) {
@ -169,22 +182,24 @@ impl MaybeInfiniteInt {
Some(m) => Finite(m), Some(m) => Finite(m),
None => JustAfterMax, None => JustAfterMax,
}, },
JustAfterMax => bug!(),
x => x, x => x,
} }
} }
} }
/// An inclusive interval, used for precise integer exhaustiveness checking. /// An inclusive interval, used for precise integer exhaustiveness checking. `IntRange`s always
/// `IntRange`s always store a contiguous range. /// store a contiguous range.
/// ///
/// `IntRange` is never used to encode an empty range or a "range" that wraps /// `IntRange` is never used to encode an empty range or a "range" that wraps around the (offset)
/// around the (offset) space: i.e., `range.lo <= range.hi`. /// space: i.e., `range.lo <= range.hi`.
/// ///
/// The range can have open ends. /// Note: the range can be `NegInfinity..=NegInfinity` or `PosInfinity..=PosInfinity` to represent
/// the values before `isize::MIN` and after `isize::MAX`/`usize::MAX`.
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct IntRange { pub(crate) struct IntRange {
pub(crate) lo: MaybeInfiniteInt, // Must not be `PosInfinity`. pub(crate) lo: MaybeInfiniteInt,
pub(crate) hi: MaybeInfiniteInt, // Must not be `NegInfinity`. pub(crate) hi: MaybeInfiniteInt,
} }
impl IntRange { impl IntRange {
@ -195,9 +210,7 @@ impl IntRange {
/// Best effort; will not know that e.g. `255u8..` is a singleton. /// Best effort; will not know that e.g. `255u8..` is a singleton.
pub(super) fn is_singleton(&self) -> bool { pub(super) fn is_singleton(&self) -> bool {
// Since `lo` and `hi` can't be the same `Infinity`, this correctly only detects a self.lo == self.hi && self.lo.is_finite()
// `Finite(x)` singleton.
self.lo == self.hi
} }
#[inline] #[inline]
@ -310,18 +323,49 @@ impl IntRange {
}) })
} }
/// Whether the range denotes the values before `isize::MIN` or the values after
/// `usize::MAX`/`isize::MAX`.
pub(crate) fn is_beyond_boundaries<'tcx>(&self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
// First check if we are usize/isize to avoid unnecessary `to_pat_range_bdy`.
ty.is_ptr_sized_integral() && !tcx.features().precise_pointer_size_matching && {
let lo = self.lo.to_pat_range_bdy(ty, tcx);
let hi = self.hi.to_pat_range_bdy(ty, tcx);
matches!(lo, PatRangeBoundary::PosInfinity)
|| matches!(hi, PatRangeBoundary::NegInfinity)
}
}
/// Only used for displaying the range. /// Only used for displaying the range.
pub(super) fn to_pat<'tcx>(&self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Pat<'tcx> { pub(super) fn to_pat<'tcx>(&self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Pat<'tcx> {
let lo = self.lo.to_pat_range_bdy(ty, tcx); let kind = if matches!((self.lo, self.hi), (NegInfinity, PosInfinity)) {
let hi = self.hi.to_pat_range_bdy(ty, tcx); PatKind::Wild
} else if self.is_singleton() {
let kind = if self.is_singleton() { let lo = self.lo.to_pat_range_bdy(ty, tcx);
let value = lo.as_finite().unwrap(); let value = lo.as_finite().unwrap();
PatKind::Constant { value } PatKind::Constant { value }
} else if matches!((self.lo, self.hi), (NegInfinity, PosInfinity)) {
PatKind::Wild
} else { } else {
PatKind::Range(Box::new(PatRange { lo, hi, end: RangeEnd::Included, ty })) let mut lo = self.lo.to_pat_range_bdy(ty, tcx);
let mut hi = self.hi.to_pat_range_bdy(ty, tcx);
let end = if hi.is_finite() {
RangeEnd::Included
} else {
// `0..=` isn't a valid pattern.
RangeEnd::Excluded
};
if matches!(hi, PatRangeBoundary::NegInfinity) {
// The range denotes the values before `isize::MIN`.
let c = ty.numeric_min_val(tcx).unwrap();
let value = mir::Const::from_ty_const(c, tcx);
hi = PatRangeBoundary::Finite(value);
}
if matches!(lo, PatRangeBoundary::PosInfinity) {
// The range denotes the values after `usize::MAX`/`isize::MAX`.
// We represent this as `usize::MAX..` which is slightly incorrect but probably
// clear enough.
let c = ty.numeric_max_val(tcx).unwrap();
let value = mir::Const::from_ty_const(c, tcx);
lo = PatRangeBoundary::Finite(value);
}
PatKind::Range(Box::new(PatRange { lo, hi, end, ty }))
}; };
Pat { ty, span: DUMMY_SP, kind } Pat { ty, span: DUMMY_SP, kind }
@ -843,9 +887,7 @@ pub(super) enum ConstructorSet {
Bool, Bool,
/// The type is spanned by integer values. The range or ranges give the set of allowed values. /// The type is spanned by integer values. The range or ranges give the set of allowed values.
/// The second range is only useful for `char`. /// The second range is only useful for `char`.
/// `non_exhaustive` is used when the range is not allowed to be matched exhaustively (that's Integers { range_1: IntRange, range_2: Option<IntRange> },
/// for usize/isize).
Integers { range_1: IntRange, range_2: Option<IntRange>, non_exhaustive: bool },
/// The type is matched by slices. The usize is the compile-time length of the array, if known. /// The type is matched by slices. The usize is the compile-time length of the array, if known.
Slice(Option<usize>), Slice(Option<usize>),
/// The type is matched by slices whose elements are uninhabited. /// The type is matched by slices whose elements are uninhabited.
@ -903,27 +945,37 @@ impl ConstructorSet {
Self::Integers { Self::Integers {
range_1: make_range('\u{0000}' as u128, '\u{D7FF}' as u128), range_1: make_range('\u{0000}' as u128, '\u{D7FF}' as u128),
range_2: Some(make_range('\u{E000}' as u128, '\u{10FFFF}' as u128)), range_2: Some(make_range('\u{E000}' as u128, '\u{10FFFF}' as u128)),
non_exhaustive: false,
} }
} }
&ty::Int(ity) => { &ty::Int(ity) => {
// `usize`/`isize` are not allowed to be matched exhaustively unless the let range = if ty.is_ptr_sized_integral()
// `precise_pointer_size_matching` feature is enabled. && !cx.tcx.features().precise_pointer_size_matching
let non_exhaustive = {
ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching; // The min/max values of `isize` are not allowed to be observed unless the
let bits = Integer::from_int_ty(&cx.tcx, ity).size().bits() as u128; // `precise_pointer_size_matching` feature is enabled.
let min = 1u128 << (bits - 1); IntRange { lo: NegInfinity, hi: PosInfinity }
let max = min - 1; } else {
Self::Integers { range_1: make_range(min, max), non_exhaustive, range_2: None } let bits = Integer::from_int_ty(&cx.tcx, ity).size().bits() as u128;
let min = 1u128 << (bits - 1);
let max = min - 1;
make_range(min, max)
};
Self::Integers { range_1: range, range_2: None }
} }
&ty::Uint(uty) => { &ty::Uint(uty) => {
// `usize`/`isize` are not allowed to be matched exhaustively unless the let range = if ty.is_ptr_sized_integral()
// `precise_pointer_size_matching` feature is enabled. && !cx.tcx.features().precise_pointer_size_matching
let non_exhaustive = {
ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching; // The max value of `usize` is not allowed to be observed unless the
let size = Integer::from_uint_ty(&cx.tcx, uty).size(); // `precise_pointer_size_matching` feature is enabled.
let max = size.truncate(u128::MAX); let lo = MaybeInfiniteInt::new_finite(cx.tcx, ty, 0);
Self::Integers { range_1: make_range(0, max), non_exhaustive, range_2: None } IntRange { lo, hi: PosInfinity }
} else {
let size = Integer::from_uint_ty(&cx.tcx, uty).size();
let max = size.truncate(u128::MAX);
make_range(0, max)
};
Self::Integers { range_1: range, range_2: None }
} }
ty::Array(sub_ty, len) if len.try_eval_target_usize(cx.tcx, cx.param_env).is_some() => { ty::Array(sub_ty, len) if len.try_eval_target_usize(cx.tcx, cx.param_env).is_some() => {
let len = len.eval_target_usize(cx.tcx, cx.param_env) as usize; let len = len.eval_target_usize(cx.tcx, cx.param_env) as usize;
@ -1078,7 +1130,7 @@ impl ConstructorSet {
missing.push(Bool(true)); missing.push(Bool(true));
} }
} }
ConstructorSet::Integers { range_1, range_2, non_exhaustive } => { ConstructorSet::Integers { range_1, range_2 } => {
let seen_ranges: Vec<_> = let seen_ranges: Vec<_> =
seen.map(|ctor| ctor.as_int_range().unwrap().clone()).collect(); seen.map(|ctor| ctor.as_int_range().unwrap().clone()).collect();
for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) { for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) {
@ -1095,10 +1147,6 @@ impl ConstructorSet {
} }
} }
} }
if *non_exhaustive {
missing.push(NonExhaustive);
}
} }
&ConstructorSet::Slice(array_len) => { &ConstructorSet::Slice(array_len) => {
let seen_slices = seen.map(|c| c.as_slice().unwrap()); let seen_slices = seen.map(|c| c.as_slice().unwrap());

View file

@ -1,17 +1,17 @@
fn main() { fn main() {
match 0usize { match 0usize {
//~^ ERROR non-exhaustive patterns: `_` not covered //~^ ERROR non-exhaustive patterns: `usize::MAX..` not covered
//~| NOTE pattern `_` not covered //~| NOTE pattern `usize::MAX..` not covered
//~| NOTE the matched value is of type `usize` //~| NOTE the matched value is of type `usize`
//~| NOTE `usize` does not have a fixed maximum value //~| NOTE `usize` does not have a fixed maximum value
0..=usize::MAX => {} 0..=usize::MAX => {}
} }
match 0isize { match 0isize {
//~^ ERROR non-exhaustive patterns: `_` not covered //~^ ERROR non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
//~| NOTE pattern `_` not covered //~| NOTE patterns `..isize::MIN` and `isize::MAX..` not covered
//~| NOTE the matched value is of type `isize` //~| NOTE the matched value is of type `isize`
//~| NOTE `isize` does not have a fixed maximum value //~| NOTE `isize` does not have fixed minimum and maximum values
isize::MIN..=isize::MAX => {} isize::MIN..=isize::MAX => {}
} }
} }

View file

@ -1,31 +1,31 @@
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/feature-gate-precise_pointer_size_matching.rs:2:11 --> $DIR/feature-gate-precise_pointer_size_matching.rs:2:11
| |
LL | match 0usize { LL | match 0usize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ 0..=usize::MAX => {}, LL ~ 0..=usize::MAX => {},
LL + _ => todo!() LL + usize::MAX.. => todo!()
| |
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11 --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
| |
LL | match 0isize { LL | match 0isize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ isize::MIN..=isize::MAX => {}, LL ~ isize::MIN..=isize::MAX => {},
LL + _ => todo!() LL + ..isize::MIN | isize::MAX.. => todo!()
| |
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: type `usize` is non-empty error[E0004]: non-exhaustive patterns: type `usize` is non-empty
--> $DIR/pointer-sized-int.rs:58:11 --> $DIR/pointer-sized-int.rs:54:11
| |
LL | match 7usize {} LL | match 7usize {}
| ^^^^^^ | ^^^^^^

View file

@ -1,218 +1,162 @@
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:14:11 --> $DIR/pointer-sized-int.rs:14:11
| |
LL | match 0usize { LL | match 0usize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ 0 ..= usize::MAX => {}, LL ~ 0 ..= usize::MAX => {},
LL + _ => todo!() LL + usize::MAX.. => todo!()
| |
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:19:11 --> $DIR/pointer-sized-int.rs:19:11
| |
LL | match 0isize { LL | match 0isize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ isize::MIN ..= isize::MAX => {}, LL ~ isize::MIN ..= isize::MAX => {},
LL + _ => todo!() LL + ..isize::MIN | isize::MAX.. => todo!()
| |
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:24:8 --> $DIR/pointer-sized-int.rs:25:8
|
LL | m!(0usize, 0..);
| ^^^^^^ pattern `_` not covered
|
= note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
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 $s { $($t)+ => {}, _ => todo!() }
| ++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/pointer-sized-int.rs:26:8
| |
LL | m!(0usize, 0..=usize::MAX); LL | m!(0usize, 0..=usize::MAX);
| ^^^^^^ pattern `_` not covered | ^^^^^^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, _ => todo!() } LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() }
| ++++++++++++++ | +++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:28:8 --> $DIR/pointer-sized-int.rs:27:8
| |
LL | m!(0usize, 0..5 | 5..=usize::MAX); LL | m!(0usize, 0..5 | 5..=usize::MAX);
| ^^^^^^ pattern `_` not covered | ^^^^^^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, _ => todo!() } LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() }
| ++++++++++++++ | +++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:30:8 --> $DIR/pointer-sized-int.rs:29:8
| |
LL | m!(0usize, 0..usize::MAX | usize::MAX); LL | m!(0usize, 0..usize::MAX | usize::MAX);
| ^^^^^^ pattern `_` not covered | ^^^^^^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, _ => todo!() } LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() }
| ++++++++++++++ | +++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `(_, _)` not covered error[E0004]: non-exhaustive patterns: `(usize::MAX.., _)` not covered
--> $DIR/pointer-sized-int.rs:32:8 --> $DIR/pointer-sized-int.rs:31:8
| |
LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
| ^^^^^^^^^^^^^^ pattern `(_, _)` not covered | ^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered
| |
= note: the matched value is of type `(usize, bool)` = note: the matched value is of type `(usize, bool)`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, (_, _) => todo!() } LL | match $s { $($t)+ => {}, (usize::MAX.., _) => todo!() }
| +++++++++++++++++++ | ++++++++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:34:8 --> $DIR/pointer-sized-int.rs:36:8
|
LL | m!(0usize, 0..=usize::MAX | usize::MAX..);
| ^^^^^^ pattern `_` not covered
|
= note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
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 $s { $($t)+ => {}, _ => todo!() }
| ++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/pointer-sized-int.rs:37:8
|
LL | m!(0isize, ..0 | 0..);
| ^^^^^^ pattern `_` not covered
|
= note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
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 $s { $($t)+ => {}, _ => todo!() }
| ++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/pointer-sized-int.rs:39:8
| |
LL | m!(0isize, isize::MIN..=isize::MAX); LL | m!(0isize, isize::MIN..=isize::MAX);
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, _ => todo!() } LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
| ++++++++++++++ | ++++++++++++++++++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:41:8 --> $DIR/pointer-sized-int.rs:38:8
| |
LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX); LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX);
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, _ => todo!() } LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
| ++++++++++++++ | ++++++++++++++++++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:43:8 --> $DIR/pointer-sized-int.rs:40:8
| |
LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX); LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX);
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, _ => todo!() } LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() }
| ++++++++++++++ | ++++++++++++++++++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `(_, _)` not covered error[E0004]: non-exhaustive patterns: `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered
--> $DIR/pointer-sized-int.rs:45:8 --> $DIR/pointer-sized-int.rs:42:8
| |
LL | m!((0isize, true), (isize::MIN..5, true) LL | m!((0isize, true), (isize::MIN..5, true)
| ^^^^^^^^^^^^^^ pattern `(_, _)` not covered | ^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered
| |
= note: the matched value is of type `(isize, bool)` = note: the matched value is of type `(isize, bool)`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 $s { $($t)+ => {}, (_, _) => todo!() } LL | match $s { $($t)+ => {}, (..isize::MIN, _) | (isize::MAX.., _) => todo!() }
| +++++++++++++++++++ | ++++++++++++++++++++++++++++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/pointer-sized-int.rs:48:8 --> $DIR/pointer-sized-int.rs:47:11
|
LL | m!(0isize, ..=isize::MIN | isize::MIN..=isize::MAX | isize::MAX..);
| ^^^^^^ pattern `_` not covered
|
= note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
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 $s { $($t)+ => {}, _ => todo!() }
| ++++++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/pointer-sized-int.rs:51:11
| |
LL | match 0isize { LL | match 0isize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ 1 ..= isize::MAX => {}, LL ~ 1 ..= isize::MAX => {},
LL + _ => todo!() LL + ..isize::MIN | isize::MAX.. => todo!()
| |
error[E0004]: non-exhaustive patterns: type `usize` is non-empty error[E0004]: non-exhaustive patterns: type `usize` is non-empty
--> $DIR/pointer-sized-int.rs:58:11 --> $DIR/pointer-sized-int.rs:54:11
| |
LL | match 7usize {} LL | match 7usize {}
| ^^^^^^ | ^^^^^^
@ -225,6 +169,6 @@ LL + _ => todo!(),
LL + } LL + }
| |
error: aborting due to 16 previous errors error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0004`. For more information about this error, try `rustc --explain E0004`.

View file

@ -22,7 +22,6 @@ fn main() {
} }
m!(0usize, 0..); m!(0usize, 0..);
//[deny]~^ ERROR non-exhaustive patterns
m!(0usize, 0..=usize::MAX); m!(0usize, 0..=usize::MAX);
//[deny]~^ ERROR non-exhaustive patterns //[deny]~^ ERROR non-exhaustive patterns
m!(0usize, 0..5 | 5..=usize::MAX); m!(0usize, 0..5 | 5..=usize::MAX);
@ -32,10 +31,8 @@ fn main() {
m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
//[deny]~^ ERROR non-exhaustive patterns //[deny]~^ ERROR non-exhaustive patterns
m!(0usize, 0..=usize::MAX | usize::MAX..); m!(0usize, 0..=usize::MAX | usize::MAX..);
//[deny]~^ ERROR non-exhaustive patterns
m!(0isize, ..0 | 0..); m!(0isize, ..0 | 0..);
//[deny]~^ ERROR non-exhaustive patterns
m!(0isize, isize::MIN..=isize::MAX); m!(0isize, isize::MIN..=isize::MAX);
//[deny]~^ ERROR non-exhaustive patterns //[deny]~^ ERROR non-exhaustive patterns
m!(0isize, isize::MIN..5 | 5..=isize::MAX); m!(0isize, isize::MIN..5 | 5..=isize::MAX);
@ -46,7 +43,6 @@ fn main() {
| (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false)); | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false));
//[deny]~^^ ERROR non-exhaustive patterns //[deny]~^^ ERROR non-exhaustive patterns
m!(0isize, ..=isize::MIN | isize::MIN..=isize::MAX | isize::MAX..); m!(0isize, ..=isize::MIN | isize::MIN..=isize::MAX | isize::MAX..);
//[deny]~^ ERROR non-exhaustive patterns
match 0isize { match 0isize {
//[deny]~^ ERROR non-exhaustive patterns //[deny]~^ ERROR non-exhaustive patterns

View file

@ -1,18 +1,18 @@
// This tests that the lint message explains the reason for the error. // This tests that the lint message explains the reason for the error.
fn main() { fn main() {
match 0usize { match 0usize {
//~^ ERROR non-exhaustive patterns: `_` not covered //~^ ERROR non-exhaustive patterns: `usize::MAX..` not covered
//~| NOTE pattern `_` not covered //~| NOTE pattern `usize::MAX..` not covered
//~| NOTE the matched value is of type `usize` //~| NOTE the matched value is of type `usize`
//~| NOTE `usize` does not have a fixed maximum value //~| NOTE `usize` does not have a fixed maximum value
0..=usize::MAX => {} 0..=usize::MAX => {}
} }
match 0isize { match 0isize {
//~^ ERROR non-exhaustive patterns: `_` not covered //~^ ERROR non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
//~| NOTE pattern `_` not covered //~| NOTE patterns `..isize::MIN` and `isize::MAX..` not covered
//~| NOTE the matched value is of type `isize` //~| NOTE the matched value is of type `isize`
//~| NOTE `isize` does not have a fixed maximum value //~| NOTE `isize` does not have fixed minimum and maximum values
isize::MIN..=isize::MAX => {} isize::MIN..=isize::MAX => {}
} }
} }

View file

@ -1,31 +1,31 @@
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/precise_pointer_matching-message.rs:3:11 --> $DIR/precise_pointer_matching-message.rs:3:11
| |
LL | match 0usize { LL | match 0usize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ 0..=usize::MAX => {}, LL ~ 0..=usize::MAX => {},
LL + _ => todo!() LL + usize::MAX.. => todo!()
| |
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered
--> $DIR/precise_pointer_matching-message.rs:11:11 --> $DIR/precise_pointer_matching-message.rs:11:11
| |
LL | match 0isize { LL | match 0isize {
| ^^^^^^ pattern `_` not covered | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ isize::MIN..=isize::MAX => {}, LL ~ isize::MIN..=isize::MAX => {},
LL + _ => todo!() LL + ..isize::MIN | isize::MAX.. => todo!()
| |
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -6,19 +6,19 @@ struct B<T, U>(T, U);
fn main() { fn main() {
match 0 { match 0 {
//~^ ERROR non-exhaustive patterns: `_` not covered [E0004] //~^ ERROR non-exhaustive patterns: `usize::MAX..` not covered [E0004]
0 => (), 0 => (),
1..=usize::MAX => (), 1..=usize::MAX => (),
} }
match (0usize, 0usize) { match (0usize, 0usize) {
//~^ ERROR non-exhaustive patterns: `(_, _)` not covered [E0004] //~^ ERROR non-exhaustive patterns: `(usize::MAX.., _)` not covered [E0004]
(0, 0) => (), (0, 0) => (),
(1..=usize::MAX, 1..=usize::MAX) => (), (1..=usize::MAX, 1..=usize::MAX) => (),
} }
match (0isize, 0usize) { match (0isize, 0usize) {
//~^ ERROR non-exhaustive patterns: `(_, _)` not covered [E0004] //~^ ERROR non-exhaustive patterns: `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered [E0004]
(isize::MIN..=isize::MAX, 0) => (), (isize::MIN..=isize::MAX, 0) => (),
(isize::MIN..=isize::MAX, 1..=usize::MAX) => (), (isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
} }
@ -30,14 +30,14 @@ fn main() {
} }
match Some(4) { match Some(4) {
//~^ ERROR non-exhaustive patterns: `Some(_)` not covered //~^ ERROR non-exhaustive patterns: `Some(usize::MAX..)` not covered
Some(0) => (), Some(0) => (),
Some(1..=usize::MAX) => (), Some(1..=usize::MAX) => (),
None => (), None => (),
} }
match Some(Some(Some(0))) { match Some(Some(Some(0))) {
//~^ ERROR non-exhaustive patterns: `Some(Some(Some(_)))` not covered //~^ ERROR non-exhaustive patterns: `Some(Some(Some(usize::MAX..)))` not covered
Some(Some(Some(0))) => (), Some(Some(Some(0))) => (),
Some(Some(Some(1..=usize::MAX))) => (), Some(Some(Some(1..=usize::MAX))) => (),
Some(Some(None)) => (), Some(Some(None)) => (),
@ -46,13 +46,13 @@ fn main() {
} }
match (A { a: 0usize }) { match (A { a: 0usize }) {
//~^ ERROR non-exhaustive patterns: `A { .. }` not covered [E0004] //~^ ERROR non-exhaustive patterns: `A { a: usize::MAX.. }` not covered [E0004]
A { a: 0 } => (), A { a: 0 } => (),
A { a: 1..=usize::MAX } => (), A { a: 1..=usize::MAX } => (),
} }
match B(0isize, 0usize) { match B(0isize, 0usize) {
//~^ ERROR non-exhaustive patterns: `B(_, _)` not covered [E0004] //~^ ERROR non-exhaustive patterns: `B(..isize::MIN, _)` and `B(isize::MAX.., _)` not covered [E0004]
B(isize::MIN..=isize::MAX, 0) => (), B(isize::MIN..=isize::MAX, 0) => (),
B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (), B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
} }
@ -60,7 +60,7 @@ fn main() {
// Should report only the note about usize not having fixed max value and not report // Should report only the note about usize not having fixed max value and not report
// report the note about isize // report the note about isize
match B(0isize, 0usize) { match B(0isize, 0usize) {
//~^ ERROR non-exhaustive patterns: `B(_, _)` not covered [E0004] //~^ ERROR non-exhaustive patterns: `B(_, usize::MAX..)` not covered [E0004]
B(_, 0) => (), B(_, 0) => (),
B(_, 1..=usize::MAX) => (), B(_, 1..=usize::MAX) => (),
} }

View file

@ -1,46 +1,46 @@
error[E0004]: non-exhaustive patterns: `_` not covered error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:8:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:8:11
| |
LL | match 0 { LL | match 0 {
| ^ pattern `_` not covered | ^ pattern `usize::MAX..` not covered
| |
= note: the matched value is of type `usize` = note: the matched value is of type `usize`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ 1..=usize::MAX => (), LL ~ 1..=usize::MAX => (),
LL ~ _ => todo!(), LL ~ usize::MAX.. => todo!(),
| |
error[E0004]: non-exhaustive patterns: `(_, _)` not covered error[E0004]: non-exhaustive patterns: `(usize::MAX.., _)` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:14:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:14:11
| |
LL | match (0usize, 0usize) { LL | match (0usize, 0usize) {
| ^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered | ^^^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered
| |
= note: the matched value is of type `(usize, usize)` = note: the matched value is of type `(usize, usize)`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ (1..=usize::MAX, 1..=usize::MAX) => (), LL ~ (1..=usize::MAX, 1..=usize::MAX) => (),
LL ~ (_, _) => todo!(), LL ~ (usize::MAX.., _) => todo!(),
| |
error[E0004]: non-exhaustive patterns: `(_, _)` not covered error[E0004]: non-exhaustive patterns: `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:20:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:20:11
| |
LL | match (0isize, 0usize) { LL | match (0isize, 0usize) {
| ^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered | ^^^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered
| |
= note: the matched value is of type `(isize, usize)` = note: the matched value is of type `(isize, usize)`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ (isize::MIN..=isize::MAX, 1..=usize::MAX) => (), LL ~ (isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
LL ~ (_, _) => todo!(), LL ~ (..isize::MIN, _) | (isize::MAX.., _) => todo!(),
| |
error[E0004]: non-exhaustive patterns: `Some(_)` not covered error[E0004]: non-exhaustive patterns: `Some(_)` not covered
@ -61,11 +61,11 @@ LL ~ None => {},
LL + Some(_) => todo!() LL + Some(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `Some(_)` not covered error[E0004]: non-exhaustive patterns: `Some(usize::MAX..)` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:32:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:32:11
| |
LL | match Some(4) { LL | match Some(4) {
| ^^^^^^^ pattern `Some(_)` not covered | ^^^^^^^ pattern `Some(usize::MAX..)` not covered
| |
note: `Option<usize>` defined here note: `Option<usize>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL --> $SRC_DIR/core/src/option.rs:LL:COL
@ -73,19 +73,19 @@ note: `Option<usize>` defined here
| |
= note: not covered = note: not covered
= note: the matched value is of type `Option<usize>` = note: the matched value is of type `Option<usize>`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ None => (),
LL ~ Some(_) => todo!(), LL ~ Some(usize::MAX..) => todo!(),
| |
error[E0004]: non-exhaustive patterns: `Some(Some(Some(_)))` not covered error[E0004]: non-exhaustive patterns: `Some(Some(Some(usize::MAX..)))` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:39:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:39:11
| |
LL | match Some(Some(Some(0))) { LL | match Some(Some(Some(0))) {
| ^^^^^^^^^^^^^^^^^^^ pattern `Some(Some(Some(_)))` not covered | ^^^^^^^^^^^^^^^^^^^ pattern `Some(Some(Some(usize::MAX..)))` not covered
| |
note: `Option<Option<Option<usize>>>` defined here note: `Option<Option<Option<usize>>>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL --> $SRC_DIR/core/src/option.rs:LL:COL
@ -97,19 +97,19 @@ note: `Option<Option<Option<usize>>>` defined here
| |
= note: not covered = note: not covered
= note: the matched value is of type `Option<Option<Option<usize>>>` = note: the matched value is of type `Option<Option<Option<usize>>>`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ None => (),
LL ~ Some(Some(Some(_))) => todo!(), LL ~ Some(Some(Some(usize::MAX..))) => todo!(),
| |
error[E0004]: non-exhaustive patterns: `A { .. }` not covered error[E0004]: non-exhaustive patterns: `A { a: usize::MAX.. }` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:48:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:48:11
| |
LL | match (A { a: 0usize }) { LL | match (A { a: 0usize }) {
| ^^^^^^^^^^^^^^^^^ pattern `A { .. }` not covered | ^^^^^^^^^^^^^^^^^ pattern `A { a: usize::MAX.. }` not covered
| |
note: `A<usize>` defined here note: `A<usize>` defined here
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:1:8 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:1:8
@ -117,19 +117,19 @@ note: `A<usize>` defined here
LL | struct A<T> { LL | struct A<T> {
| ^ | ^
= note: the matched value is of type `A<usize>` = note: the matched value is of type `A<usize>`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 { a: 1..=usize::MAX } => (), LL ~ A { a: 1..=usize::MAX } => (),
LL ~ A { .. } => todo!(), LL ~ A { a: usize::MAX.. } => todo!(),
| |
error[E0004]: non-exhaustive patterns: `B(_, _)` not covered error[E0004]: non-exhaustive patterns: `B(..isize::MIN, _)` and `B(isize::MAX.., _)` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:54:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:54:11
| |
LL | match B(0isize, 0usize) { LL | match B(0isize, 0usize) {
| ^^^^^^^^^^^^^^^^^ pattern `B(_, _)` not covered | ^^^^^^^^^^^^^^^^^ patterns `B(..isize::MIN, _)` and `B(isize::MAX.., _)` not covered
| |
note: `B<isize, usize>` defined here note: `B<isize, usize>` defined here
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:5:8 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:5:8
@ -137,19 +137,19 @@ note: `B<isize, usize>` defined here
LL | struct B<T, U>(T, U); LL | struct B<T, U>(T, U);
| ^ | ^
= note: the matched value is of type `B<isize, usize>` = note: the matched value is of type `B<isize, usize>`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (), LL ~ B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
LL ~ B(_, _) => todo!(), LL ~ B(..isize::MIN, _) | B(isize::MAX.., _) => todo!(),
| |
error[E0004]: non-exhaustive patterns: `B(_, _)` not covered error[E0004]: non-exhaustive patterns: `B(_, usize::MAX..)` not covered
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:62:11 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:62:11
| |
LL | match B(0isize, 0usize) { LL | match B(0isize, 0usize) {
| ^^^^^^^^^^^^^^^^^ pattern `B(_, _)` not covered | ^^^^^^^^^^^^^^^^^ pattern `B(_, usize::MAX..)` not covered
| |
note: `B<isize, usize>` defined here note: `B<isize, usize>` defined here
--> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:5:8 --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:5:8
@ -157,12 +157,12 @@ note: `B<isize, usize>` defined here
LL | struct B<T, U>(T, U); LL | struct B<T, U>(T, U);
| ^ | ^
= note: the matched value is of type `B<isize, usize>` = note: the matched value is of type `B<isize, usize>`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ B(_, 1..=usize::MAX) => (), LL ~ B(_, 1..=usize::MAX) => (),
LL ~ B(_, _) => todo!(), LL ~ B(_, usize::MAX..) => todo!(),
| |
error: aborting due to 9 previous errors error: aborting due to 9 previous errors

View file

@ -1,88 +1,101 @@
struct Foo { struct Foo {
first: bool, first: bool,
second: Option<[usize; 4]> second: Option<[usize; 4]>,
} }
fn struct_with_a_nested_enum_and_vector() { fn struct_with_a_nested_enum_and_vector() {
match (Foo { first: true, second: None }) { match (Foo { first: true, second: None }) {
//~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered //~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([0_usize, _, _, _]) }` and `Foo { first: false, second: Some([2_usize.., _, _, _]) }` not covered
Foo { first: true, second: None } => (), Foo { first: true, second: None } => (),
Foo { first: true, second: Some(_) } => (), Foo { first: true, second: Some(_) } => (),
Foo { first: false, second: None } => (), Foo { first: false, second: None } => (),
Foo { first: false, second: Some([1, 2, 3, 4]) } => () Foo { first: false, second: Some([1, 2, 3, 4]) } => (),
} }
} }
enum Color { enum Color {
Red, Red,
Green, Green,
CustomRGBA { a: bool, r: u8, g: u8, b: u8 } CustomRGBA { a: bool, r: u8, g: u8, b: u8 },
} }
fn enum_with_single_missing_variant() { fn enum_with_single_missing_variant() {
match Color::Red { match Color::Red {
//~^ ERROR non-exhaustive patterns: `Color::Red` not covered //~^ ERROR non-exhaustive patterns: `Color::Red` not covered
Color::CustomRGBA { .. } => (), Color::CustomRGBA { .. } => (),
Color::Green => () Color::Green => (),
} }
} }
enum Direction { enum Direction {
North, East, South, West North,
East,
South,
West,
} }
fn enum_with_multiple_missing_variants() { fn enum_with_multiple_missing_variants() {
match Direction::North { match Direction::North {
//~^ ERROR non-exhaustive patterns: `Direction::East`, `Direction::South` and `Direction::West` not covered //~^ ERROR non-exhaustive patterns: `Direction::East`, `Direction::South` and `Direction::West` not covered
Direction::North => () Direction::North => (),
} }
} }
enum ExcessiveEnum { enum ExcessiveEnum {
First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth First,
Second,
Third,
Fourth,
Fifth,
Sixth,
Seventh,
Eighth,
Ninth,
Tenth,
Eleventh,
Twelfth,
} }
fn enum_with_excessive_missing_variants() { fn enum_with_excessive_missing_variants() {
match ExcessiveEnum::First { match ExcessiveEnum::First {
//~^ ERROR `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered //~^ ERROR `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered
ExcessiveEnum::First => (),
ExcessiveEnum::First => ()
} }
} }
fn enum_struct_variant() { fn enum_struct_variant() {
match Color::Red { match Color::Red {
//~^ ERROR non-exhaustive patterns: `Color::CustomRGBA { a: true, .. }` not covered //~^ ERROR non-exhaustive patterns: `Color::CustomRGBA { a: true, .. }` not covered
Color::Red => (), Color::Red => (),
Color::Green => (), Color::Green => (),
Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (), Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
Color::CustomRGBA { a: false, r: _, g: _, b: _ } => () Color::CustomRGBA { a: false, r: _, g: _, b: _ } => (),
} }
} }
enum Enum { enum Enum {
First, First,
Second(bool) Second(bool),
} }
fn vectors_with_nested_enums() { fn vectors_with_nested_enums() {
let x: &'static [Enum] = &[Enum::First, Enum::Second(false)]; let x: &'static [Enum] = &[Enum::First, Enum::Second(false)];
match *x { match *x {
//~^ ERROR non-exhaustive patterns: `[Enum::Second(true), Enum::Second(false)]` not covered //~^ ERROR non-exhaustive patterns: `[Enum::Second(true), Enum::Second(false)]` not covered
[] => (), [] => (),
[_] => (), [_] => (),
[Enum::First, _] => (), [Enum::First, _] => (),
[Enum::Second(true), Enum::First] => (), [Enum::Second(true), Enum::First] => (),
[Enum::Second(true), Enum::Second(true)] => (), [Enum::Second(true), Enum::Second(true)] => (),
[Enum::Second(false), _] => (), [Enum::Second(false), _] => (),
[_, _, ref tail @ .., _] => () [_, _, ref tail @ .., _] => (),
} }
} }
fn missing_nil() { fn missing_nil() {
match ((), false) { match ((), false) {
//~^ ERROR non-exhaustive patterns: `((), false)` not covered //~^ ERROR non-exhaustive patterns: `((), false)` not covered
((), true) => () ((), true) => (),
} }
} }

View file

@ -1,8 +1,8 @@
error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([0_usize, _, _, _]) }` and `Foo { first: false, second: Some([2_usize.., _, _, _]) }` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:7:11 --> $DIR/non-exhaustive-pattern-witness.rs:7:11
| |
LL | match (Foo { first: true, second: None }) { LL | match (Foo { first: true, second: None }) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo { first: false, second: Some([0_usize, _, _, _]) }` and `Foo { first: false, second: Some([2_usize.., _, _, _]) }` not covered
| |
note: `Foo` defined here note: `Foo` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:1:8 --> $DIR/non-exhaustive-pattern-witness.rs:1:8
@ -10,12 +10,10 @@ note: `Foo` defined here
LL | struct Foo { LL | struct Foo {
| ^^^ | ^^^
= note: the matched value is of type `Foo` = note: the matched value is of type `Foo`
= note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively 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
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
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 ~ Foo { first: false, second: Some([1, 2, 3, 4]) } => (), LL ~ Foo { first: false, second: Some([1, 2, 3, 4]) } => (),
LL + Foo { first: false, second: Some([_, _, _, _]) } => todo!() LL ~ Foo { first: false, second: Some([0_usize, _, _, _]) } | Foo { first: false, second: Some([2_usize.., _, _, _]) } => todo!(),
| |
error[E0004]: non-exhaustive patterns: `Color::Red` not covered error[E0004]: non-exhaustive patterns: `Color::Red` not covered
@ -35,40 +33,42 @@ LL | Red,
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ Color::Green => (), LL ~ Color::Green => (),
LL + Color::Red => todo!() LL ~ Color::Red => todo!(),
| |
error[E0004]: non-exhaustive patterns: `Direction::East`, `Direction::South` and `Direction::West` not covered error[E0004]: non-exhaustive patterns: `Direction::East`, `Direction::South` and `Direction::West` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:35:11 --> $DIR/non-exhaustive-pattern-witness.rs:38:11
| |
LL | match Direction::North { LL | match Direction::North {
| ^^^^^^^^^^^^^^^^ patterns `Direction::East`, `Direction::South` and `Direction::West` not covered | ^^^^^^^^^^^^^^^^ patterns `Direction::East`, `Direction::South` and `Direction::West` not covered
| |
note: `Direction` defined here note: `Direction` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:31:12 --> $DIR/non-exhaustive-pattern-witness.rs:32:5
| |
LL | enum Direction { LL | enum Direction {
| --------- | ---------
LL | North, East, South, West LL | North,
| ^^^^ ^^^^^ ^^^^ not covered LL | East,
| | | | ^^^^ not covered
| | not covered LL | South,
| not covered | ^^^^^ not covered
LL | West,
| ^^^^ not covered
= note: the matched value is of type `Direction` = note: the matched value is of type `Direction`
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 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 ~ Direction::North => (), LL ~ Direction::North => (),
LL + Direction::East | Direction::South | Direction::West => todo!() LL ~ Direction::East | Direction::South | Direction::West => todo!(),
| |
error[E0004]: non-exhaustive patterns: `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered error[E0004]: non-exhaustive patterns: `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered
--> $DIR/non-exhaustive-pattern-witness.rs:46:11 --> $DIR/non-exhaustive-pattern-witness.rs:60:11
| |
LL | match ExcessiveEnum::First { LL | match ExcessiveEnum::First {
| ^^^^^^^^^^^^^^^^^^^^ patterns `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered | ^^^^^^^^^^^^^^^^^^^^ patterns `ExcessiveEnum::Second`, `ExcessiveEnum::Third`, `ExcessiveEnum::Fourth` and 8 more not covered
| |
note: `ExcessiveEnum` defined here note: `ExcessiveEnum` defined here
--> $DIR/non-exhaustive-pattern-witness.rs:41:6 --> $DIR/non-exhaustive-pattern-witness.rs:44:6
| |
LL | enum ExcessiveEnum { LL | enum ExcessiveEnum {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -76,11 +76,11 @@ LL | enum ExcessiveEnum {
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
| |
LL ~ ExcessiveEnum::First => (), LL ~ ExcessiveEnum::First => (),
LL + _ => todo!() LL ~ _ => todo!(),
| |
error[E0004]: non-exhaustive patterns: `Color::CustomRGBA { a: true, .. }` not covered error[E0004]: non-exhaustive patterns: `Color::CustomRGBA { a: true, .. }` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:54:11 --> $DIR/non-exhaustive-pattern-witness.rs:67:11
| |
LL | match Color::Red { LL | match Color::Red {
| ^^^^^^^^^^ pattern `Color::CustomRGBA { a: true, .. }` not covered | ^^^^^^^^^^ pattern `Color::CustomRGBA { a: true, .. }` not covered
@ -91,17 +91,17 @@ note: `Color` defined here
LL | enum Color { LL | enum Color {
| ----- | -----
... ...
LL | CustomRGBA { a: bool, r: u8, g: u8, b: u8 } LL | CustomRGBA { a: bool, r: u8, g: u8, b: u8 },
| ^^^^^^^^^^ not covered | ^^^^^^^^^^ not covered
= note: the matched value is of type `Color` = note: the matched value is of type `Color`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ Color::CustomRGBA { a: false, r: _, g: _, b: _ } => (), LL ~ Color::CustomRGBA { a: false, r: _, g: _, b: _ } => (),
LL + Color::CustomRGBA { a: true, .. } => todo!() LL ~ Color::CustomRGBA { a: true, .. } => todo!(),
| |
error[E0004]: non-exhaustive patterns: `[Enum::Second(true), Enum::Second(false)]` not covered error[E0004]: non-exhaustive patterns: `[Enum::Second(true), Enum::Second(false)]` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:70:11 --> $DIR/non-exhaustive-pattern-witness.rs:83:11
| |
LL | match *x { LL | match *x {
| ^^ pattern `[Enum::Second(true), Enum::Second(false)]` not covered | ^^ pattern `[Enum::Second(true), Enum::Second(false)]` not covered
@ -110,11 +110,11 @@ LL | match *x {
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ [_, _, ref tail @ .., _] => (), LL ~ [_, _, ref tail @ .., _] => (),
LL + [Enum::Second(true), Enum::Second(false)] => todo!() LL ~ [Enum::Second(true), Enum::Second(false)] => todo!(),
| |
error[E0004]: non-exhaustive patterns: `((), false)` not covered error[E0004]: non-exhaustive patterns: `((), false)` not covered
--> $DIR/non-exhaustive-pattern-witness.rs:83:11 --> $DIR/non-exhaustive-pattern-witness.rs:96:11
| |
LL | match ((), false) { LL | match ((), false) {
| ^^^^^^^^^^^ pattern `((), false)` not covered | ^^^^^^^^^^^ pattern `((), false)` not covered
@ -123,7 +123,7 @@ LL | match ((), false) {
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown 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 ~ ((), true) => (), LL ~ ((), true) => (),
LL + ((), false) => todo!() LL ~ ((), false) => todo!(),
| |
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View file

@ -1,6 +1,6 @@
fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { } fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) {}
//~^ ERROR refutable pattern in function argument //~^ ERROR refutable pattern in function argument
//~| `(_, _)` not covered //~| `(..=0_isize, _)` and `(2_isize.., _)` not covered
fn main() { fn main() {
let (1, (Some(1), 2..=3)) = (1, (None, 2)); let (1, (Some(1), 2..=3)) = (1, (None, 2));

View file

@ -1,8 +1,8 @@
error[E0005]: refutable pattern in function argument error[E0005]: refutable pattern in function argument
--> $DIR/refutable-pattern-errors.rs:1:9 --> $DIR/refutable-pattern-errors.rs:1:9
| |
LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { } LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) {}
| ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered | ^^^^^^^^^^^^^^^^^^^^^ patterns `(..=0_isize, _)` and `(2_isize.., _)` not covered
| |
= note: the matched value is of type `(isize, (Option<isize>, isize))` = note: the matched value is of type `(isize, (Option<isize>, isize))`

View file

@ -1,6 +1,6 @@
fn main() { fn main() {
let f = |3: isize| println!("hello"); let f = |3: isize| println!("hello");
//~^ ERROR refutable pattern in function argument //~^ ERROR refutable pattern in function argument
//~| `_` not covered //~| `..=2_isize` and `4_isize..` not covered
f(4); f(4);
} }

View file

@ -2,7 +2,7 @@ error[E0005]: refutable pattern in function argument
--> $DIR/refutable-pattern-in-fn-arg.rs:2:14 --> $DIR/refutable-pattern-in-fn-arg.rs:2:14
| |
LL | let f = |3: isize| println!("hello"); LL | let f = |3: isize| println!("hello");
| ^ pattern `_` not covered | ^ patterns `..=2_isize` and `4_isize..` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits

View file

@ -1,8 +1,8 @@
error[E0004]: non-exhaustive patterns: `Foo(_, _)` not covered error[E0004]: non-exhaustive patterns: `Foo(..=0_isize, _)` and `Foo(3_isize.., _)` not covered
--> $DIR/tuple-struct-nonexhaustive.rs:5:11 --> $DIR/tuple-struct-nonexhaustive.rs:5:11
| |
LL | match x { LL | match x {
| ^ pattern `Foo(_, _)` not covered | ^ patterns `Foo(..=0_isize, _)` and `Foo(3_isize.., _)` not covered
| |
note: `Foo` defined here note: `Foo` defined here
--> $DIR/tuple-struct-nonexhaustive.rs:1:8 --> $DIR/tuple-struct-nonexhaustive.rs:1:8
@ -10,12 +10,10 @@ note: `Foo` defined here
LL | struct Foo(isize, isize); LL | struct Foo(isize, isize);
| ^^^ | ^^^
= note: the matched value is of type `Foo` = note: the matched value is of type `Foo`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively 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
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
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 ~ Foo(2, b) => println!("{}", b), LL ~ Foo(2, b) => println!("{}", b),
LL + Foo(_, _) => todo!() LL + Foo(..=0_isize, _) | Foo(3_isize.., _) => todo!()
| |
error: aborting due to previous error error: aborting due to previous error