From 0081ef2548f95171b33bbaedcd90253cf41916b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 10 Feb 2019 05:12:00 -0800 Subject: [PATCH 1/3] Point at enum definition when match patterns are not exhaustive ``` error[E0004]: non-exhaustive patterns: type `X` is non-empty --> file.rs:9:11 | 1 | / enum X { 2 | | A, | | - variant not covered 3 | | B, | | - variant not covered 4 | | C, | | - variant not covered 5 | | } | |_- `X` defined here ... 9 | match x { | ^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `B` and `C` not covered --> file.rs:11:11 | 1 | / enum X { 2 | | A, 3 | | B, 4 | | C, | | - not covered 5 | | } | |_- `X` defined here ... 11 | match x { | ^ patterns `C` not covered ``` When a match expression doesn't have patterns covering every variant, point at the enum's definition span. On a best effort basis, point at the variant(s) that are missing. This does not handle the case when the missing pattern is due to a field's enum variants: ``` enum E1 { A, B, C, } enum E2 { A(E1), B, } fn foo() { match E2::A(E1::A) { E2::A(E1::B) => {} E2::B => {} } //~^ ERROR `E2::A(E1::A)` and `E2::A(E1::C)` not handled } ``` Unify look between match with no arms and match with some missing patterns. Fix #37518. --- src/librustc_mir/hair/pattern/_match.rs | 1 - src/librustc_mir/hair/pattern/check_match.rs | 134 ++++++++++++++---- src/test/ui/always-inhabited-union-ref.stderr | 12 +- src/test/ui/check_match/issue-35609.stderr | 22 +++ src/test/ui/consts/match_ice.stderr | 2 + src/test/ui/empty/empty-never-array.stderr | 11 +- src/test/ui/error-codes/E0004-2.stderr | 6 +- src/test/ui/error-codes/E0004.stderr | 13 +- .../ui/exhaustive_integer_patterns.stderr | 22 +++ ...-gate-precise_pointer_size_matching.stderr | 4 + src/test/ui/issues/issue-15129.stderr | 2 + src/test/ui/issues/issue-2111.stderr | 2 + src/test/ui/issues/issue-30240.stderr | 4 + src/test/ui/issues/issue-3096-1.stderr | 6 +- src/test/ui/issues/issue-3096-2.stderr | 6 +- src/test/ui/issues/issue-31561.stderr | 11 +- src/test/ui/issues/issue-3601.stderr | 2 + src/test/ui/issues/issue-39362.stderr | 11 +- src/test/ui/issues/issue-4321.stderr | 2 + src/test/ui/match/match-argm-statics-2.stderr | 16 ++- .../match/match-byte-array-patterns-2.stderr | 4 + src/test/ui/match/match-non-exhaustive.stderr | 4 + .../ui/match/match-privately-empty.stderr | 2 + src/test/ui/match/match-slice-patterns.stderr | 2 + .../missing/missing-items/issue-40221.stderr | 12 +- .../non-exhaustive-float-range-match.stderr | 2 + .../non-exhaustive-match-nested.stderr | 10 ++ .../non-exhaustive-match.stderr | 28 ++++ .../non-exhaustive-pattern-witness.stderr | 70 +++++++-- .../ui/precise_pointer_size_matching.stderr | 4 + .../slice.stderr | 2 + .../ui/rfc-2008-non-exhaustive/enum.stderr | 2 + .../struct-like-enum-nonexhaustive.stderr | 13 +- .../tuple/tuple-struct-nonexhaustive.stderr | 5 + .../uninhabited-irrefutable.stderr | 12 +- .../uninhabited-matches-feature-gated.stderr | 24 ++-- 36 files changed, 390 insertions(+), 95 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 9e9a5d0f82ada..60eb30e075339 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -539,7 +539,6 @@ impl<'tcx> Witness<'tcx> { self.apply_constructor(cx, ctor, ty) } - /// Constructs a partial witness for a pattern given a list of /// patterns expanded by the specialization step. /// diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 0f151cd688df9..96709e2ac0453 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -10,7 +10,7 @@ use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization::cmt_; use rustc::middle::region; use rustc::session::Session; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, TyKind}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::lint; use rustc_errors::{Applicability, DiagnosticBuilder}; @@ -204,25 +204,42 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { // is uninhabited. let pat_ty = self.tables.node_type(scrut.hir_id); let module = self.tcx.hir().get_module_parent_by_hir_id(scrut.hir_id); + let mut def_span = None; + let mut missing_variants = vec![]; if inlined_arms.is_empty() { let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(module, pat_ty) } else { match pat_ty.sty { ty::Never => true, - ty::Adt(def, _) => def.variants.is_empty(), + ty::Adt(def, _) => { + def_span = self.tcx.hir().span_if_local(def.did); + if def.variants.len() < 4 && !def.variants.is_empty() { + // keep around to point at the definition of non-covered variants + missing_variants = def.variants.iter() + .map(|variant| variant.ident.span) + .collect(); + } + def.variants.is_empty() + }, _ => false } }; if !scrutinee_is_uninhabited { // We know the type is inhabited, so this must be wrong - let mut err = create_e0004(self.tcx.sess, scrut.span, - format!("non-exhaustive patterns: type `{}` \ - is non-empty", - pat_ty)); - span_help!(&mut err, scrut.span, - "ensure that all possible cases are being handled, \ - possibly by adding wildcards or more match arms"); + let mut err = create_e0004(self.tcx.sess, scrut.span, format!( + "non-exhaustive patterns: type `{}` is non-empty", + pat_ty, + )); + err.help("ensure that all possible cases are being handled, \ + possibly by adding wildcards or more match arms"); + if let Some(sp) = def_span { + err.span_label(sp, format!("`{}` defined here", pat_ty)); + } + // point at the definition of non-covered enum variants + for variant in &missing_variants { + err.span_label(*variant, "variant not covered"); + } err.emit(); } // If the type *is* uninhabited, it's vacuously exhaustive @@ -264,7 +281,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { }; let pattern_string = witness[0].single_pattern().to_string(); - let mut diag = struct_span_err!( + let mut err = struct_span_err!( self.tcx.sess, pat.span, E0005, "refutable pattern in {}: `{}` not covered", origin, pattern_string @@ -277,8 +294,13 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } _ => format!("pattern `{}` not covered", pattern_string), }; - diag.span_label(pat.span, label_msg); - diag.emit(); + err.span_label(pat.span, label_msg); + if let ty::Adt(def, _) = pattern_ty.sty { + if let Some(sp) = self.tcx.hir().span_if_local(def.did){ + err.span_label(sp, format!("`{}` defined here", pattern_ty)); + } + } + err.emit(); }); } } @@ -332,10 +354,11 @@ fn pat_is_catchall(pat: &Pat) -> bool { } // Check for unreachable patterns -fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, - arms: &[(Vec<(&'a Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)], - source: hir::MatchSource) -{ +fn check_arms<'a, 'tcx>( + cx: &mut MatchCheckCtxt<'a, 'tcx>, + arms: &[(Vec<(&'a Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)], + source: hir::MatchSource, +) { let mut seen = Matrix::empty(); let mut catchall = None; for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() { @@ -411,10 +434,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, } } -fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, - scrut_ty: Ty<'tcx>, - sp: Span, - matrix: &Matrix<'p, 'tcx>) { +fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>( + cx: &mut MatchCheckCtxt<'a, 'tcx>, + scrut_ty: Ty<'tcx>, + sp: Span, + matrix: &Matrix<'p, 'tcx>, +) { let wild_pattern = Pattern { ty: scrut_ty, span: DUMMY_SP, @@ -448,11 +473,26 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, 1 => format!("pattern {} not covered", joined_patterns), _ => format!("patterns {} not covered", joined_patterns), }; - create_e0004(cx.tcx.sess, sp, - format!("non-exhaustive patterns: {} not covered", - joined_patterns)) - .span_label(sp, label_text) - .emit(); + let mut err = create_e0004(cx.tcx.sess, sp, format!( + "non-exhaustive patterns: {} not covered", + joined_patterns, + )); + err.span_label(sp, label_text); + // point at the definition of non-covered enum variants + if let ty::Adt(def, _) = scrut_ty.sty { + if let Some(sp) = cx.tcx.hir().span_if_local(def.did){ + err.span_label(sp, format!("`{}` defined here", scrut_ty)); + } + } + let patterns = witnesses.iter().map(|p| (**p).clone()).collect::>(); + if patterns.len() < 4 { + for sp in maybe_point_at_variant(cx, &scrut_ty.sty, patterns.as_slice()) { + err.span_label(sp, "not covered"); + } + } + err.help("ensure that all possible cases are being handled, \ + possibly by adding wildcards or more match arms"); + err.emit(); } NotUseful => { // This is good, wildcard pattern isn't reachable @@ -461,10 +501,48 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, } } +fn maybe_point_at_variant( + cx: &mut MatchCheckCtxt<'a, 'tcx>, + sty: &TyKind<'tcx>, + patterns: &[Pattern], +) -> Vec { + let mut covered = vec![]; + if let ty::Adt(def, _) = sty { + // Don't point at the variants if they are too many to avoid visual clutter + for pattern in patterns { + let pk: &PatternKind = &pattern.kind; + if let PatternKind::Variant { adt_def, variant_index, subpatterns, .. } = pk { + if adt_def.did == def.did { + let sp = def.variants[*variant_index].ident.span; + if covered.contains(&sp) { + continue; + } + covered.push(sp); + let subpatterns = subpatterns.iter() + .map(|field_pattern| field_pattern.pattern.clone()) + .collect::>(); + covered.extend( + maybe_point_at_variant(cx, sty, subpatterns.as_slice()), + ); + } + } + if let PatternKind::Leaf{ subpatterns } = pk { + let subpatterns = subpatterns.iter() + .map(|field_pattern| field_pattern.pattern.clone()) + .collect::>(); + covered.extend(maybe_point_at_variant(cx, sty, subpatterns.as_slice())); + } + } + } + covered +} + // Legality of move bindings checking -fn check_legality_of_move_bindings(cx: &MatchVisitor<'_, '_>, - has_guard: bool, - pats: &[P]) { +fn check_legality_of_move_bindings( + cx: &MatchVisitor<'_, '_>, + has_guard: bool, + pats: &[P], +) { let mut by_ref_span = None; for pat in pats { pat.each_binding(|_, hir_id, span, _path| { diff --git a/src/test/ui/always-inhabited-union-ref.stderr b/src/test/ui/always-inhabited-union-ref.stderr index 212f5d7c525f5..792ab6f59a439 100644 --- a/src/test/ui/always-inhabited-union-ref.stderr +++ b/src/test/ui/always-inhabited-union-ref.stderr @@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty LL | match uninhab_ref() { | ^^^^^^^^^^^^^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/always-inhabited-union-ref.rs:23:11 - | -LL | match uninhab_ref() { - | ^^^^^^^^^^^^^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `Foo` is non-empty --> $DIR/always-inhabited-union-ref.rs:27:11 @@ -16,11 +12,7 @@ error[E0004]: non-exhaustive patterns: type `Foo` is non-empty LL | match uninhab_union() { | ^^^^^^^^^^^^^^^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/always-inhabited-union-ref.rs:27:11 - | -LL | match uninhab_union() { - | ^^^^^^^^^^^^^^^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/check_match/issue-35609.stderr b/src/test/ui/check_match/issue-35609.stderr index 7a517e856cbe2..54e5c988f8ccc 100644 --- a/src/test/ui/check_match/issue-35609.stderr +++ b/src/test/ui/check_match/issue-35609.stderr @@ -3,48 +3,70 @@ error[E0004]: non-exhaustive patterns: `(B, _)`, `(C, _)`, `(D, _)` and 2 more n | LL | match (A, ()) { //~ ERROR non-exhaustive | ^^^^^^^ patterns `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered --> $DIR/issue-35609.rs:14:11 | LL | match (A, A) { //~ ERROR non-exhaustive | ^^^^^^ patterns `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered --> $DIR/issue-35609.rs:18:11 | LL | match ((A, ()), ()) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered --> $DIR/issue-35609.rs:22:11 | LL | match ((A, ()), A) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered --> $DIR/issue-35609.rs:26:11 | LL | match ((A, ()), ()) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered --> $DIR/issue-35609.rs:31:11 | +LL | struct S(Enum, ()); + | ------------------- `S` defined here +... LL | match S(A, ()) { //~ ERROR non-exhaustive | ^^^^^^^^ patterns `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered --> $DIR/issue-35609.rs:35:11 | +LL | struct Sd { x: Enum, y: () } + | ---------------------------- `Sd` defined here +... LL | match (Sd { x: A, y: () }) { //~ ERROR non-exhaustive | ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered --> $DIR/issue-35609.rs:39:11 | LL | match Some(A) { //~ ERROR non-exhaustive | ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 8 previous errors diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr index e6e04e2c46276..d984023169597 100644 --- a/src/test/ui/consts/match_ice.stderr +++ b/src/test/ui/consts/match_ice.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `&S` not covered | LL | match C { //~ ERROR non-exhaustive | ^ pattern `&S` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr index e409f14d6ce97..f1be4a6edec5f 100644 --- a/src/test/ui/empty/empty-never-array.stderr +++ b/src/test/ui/empty/empty-never-array.stderr @@ -1,8 +1,15 @@ error[E0005]: refutable pattern in local binding: `T(_, _)` not covered --> $DIR/empty-never-array.rs:10:9 | -LL | let Helper::U(u) = Helper::T(t, []); - | ^^^^^^^^^^^^ pattern `T(_, _)` not covered +LL | / enum Helper { +LL | | T(T, [!; 0]), +LL | | #[allow(dead_code)] +LL | | U(U), +LL | | } + | |_- `Helper` defined here +... +LL | let Helper::U(u) = Helper::T(t, []); + | ^^^^^^^^^^^^ pattern `T(_, _)` not covered error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index 8b262cc6eb784..94e38cf26aa4d 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `std::option::Option` is non-em LL | match x { } //~ ERROR E0004 | ^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/E0004-2.rs:4:11 - | -LL | match x { } //~ ERROR E0004 - | ^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0004.stderr b/src/test/ui/error-codes/E0004.stderr index a66dd92903200..123f4b2f1b71d 100644 --- a/src/test/ui/error-codes/E0004.stderr +++ b/src/test/ui/error-codes/E0004.stderr @@ -1,8 +1,17 @@ error[E0004]: non-exhaustive patterns: `HastaLaVistaBaby` not covered --> $DIR/E0004.rs:9:11 | -LL | match x { //~ ERROR E0004 - | ^ pattern `HastaLaVistaBaby` not covered +LL | / enum Terminator { +LL | | HastaLaVistaBaby, + | | ---------------- not covered +LL | | TalkToMyHand, +LL | | } + | |_- `Terminator` defined here +... +LL | match x { //~ ERROR E0004 + | ^ pattern `HastaLaVistaBaby` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/exhaustive_integer_patterns.stderr b/src/test/ui/exhaustive_integer_patterns.stderr index 7b873f7ba4259..d9513710d4463 100644 --- a/src/test/ui/exhaustive_integer_patterns.stderr +++ b/src/test/ui/exhaustive_integer_patterns.stderr @@ -15,12 +15,16 @@ error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered | LL | match x { //~ ERROR non-exhaustive patterns | ^ pattern `128u8..=255u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered --> $DIR/exhaustive_integer_patterns.rs:33:11 | LL | match x { //~ ERROR non-exhaustive patterns | ^ patterns `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: unreachable pattern --> $DIR/exhaustive_integer_patterns.rs:44:9 @@ -33,54 +37,72 @@ error[E0004]: non-exhaustive patterns: `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` | LL | match x { //~ ERROR non-exhaustive patterns | ^ patterns `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `-128i8` not covered --> $DIR/exhaustive_integer_patterns.rs:82:11 | LL | match 0i8 { //~ ERROR non-exhaustive patterns | ^^^ pattern `-128i8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `0i16` not covered --> $DIR/exhaustive_integer_patterns.rs:90:11 | LL | match 0i16 { //~ ERROR non-exhaustive patterns | ^^^^ pattern `0i16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered --> $DIR/exhaustive_integer_patterns.rs:108:11 | LL | match 0u8 { //~ ERROR non-exhaustive patterns | ^^^ pattern `128u8..=255u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered --> $DIR/exhaustive_integer_patterns.rs:120:11 | LL | match (0u8, Some(())) { //~ ERROR non-exhaustive patterns | ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered --> $DIR/exhaustive_integer_patterns.rs:125:11 | LL | match (0u8, true) { //~ ERROR non-exhaustive patterns | ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211455u128` not covered --> $DIR/exhaustive_integer_patterns.rs:145:11 | LL | match 0u128 { //~ ERROR non-exhaustive patterns | ^^^^^ pattern `340282366920938463463374607431768211455u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `5u128..=340282366920938463463374607431768211455u128` not covered --> $DIR/exhaustive_integer_patterns.rs:149:11 | LL | match 0u128 { //~ ERROR non-exhaustive patterns | ^^^^^ pattern `5u128..=340282366920938463463374607431768211455u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered --> $DIR/exhaustive_integer_patterns.rs:153:11 | LL | match 0u128 { //~ ERROR non-exhaustive patterns | ^^^^^ pattern `0u128..=3u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 13 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr index 5806f6f039157..fd1e5392e69e4 100644 --- a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr +++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr @@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `_` not covered | LL | match 0usize { //~ERROR non-exhaustive patterns: `_` not covered | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `_` not covered --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11 | LL | match 0isize { //~ERROR non-exhaustive patterns: `_` not covered | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-15129.stderr b/src/test/ui/issues/issue-15129.stderr index 7ee369085202b..b93fa14db0387 100644 --- a/src/test/ui/issues/issue-15129.stderr +++ b/src/test/ui/issues/issue-15129.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered | LL | match (T::T1(()), V::V2(true)) { | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2111.stderr b/src/test/ui/issues/issue-2111.stderr index 348ad153c8099..90fdb48ea625d 100644 --- a/src/test/ui/issues/issue-2111.stderr +++ b/src/test/ui/issues/issue-2111.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `(None, None)` not covered | LL | match (a,b) { | ^^^^^ pattern `(None, None)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/issues/issue-30240.stderr b/src/test/ui/issues/issue-30240.stderr index 973c59c58526b..bc538abf3bdf0 100644 --- a/src/test/ui/issues/issue-30240.stderr +++ b/src/test/ui/issues/issue-30240.stderr @@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `&_` not covered | LL | match "world" { //~ ERROR non-exhaustive patterns: `&_` | ^^^^^^^ pattern `&_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&_` not covered --> $DIR/issue-30240.rs:6:11 | LL | match "world" { //~ ERROR non-exhaustive patterns: `&_` | ^^^^^^^ pattern `&_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-3096-1.stderr b/src/test/ui/issues/issue-3096-1.stderr index 7ced0d36805dd..fee58474031e9 100644 --- a/src/test/ui/issues/issue-3096-1.stderr +++ b/src/test/ui/issues/issue-3096-1.stderr @@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `()` is non-empty LL | match () { } //~ ERROR non-exhaustive | ^^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/issue-3096-1.rs:2:11 - | -LL | match () { } //~ ERROR non-exhaustive - | ^^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3096-2.stderr b/src/test/ui/issues/issue-3096-2.stderr index df87679448956..93119d377441f 100644 --- a/src/test/ui/issues/issue-3096-2.stderr +++ b/src/test/ui/issues/issue-3096-2.stderr @@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty LL | match x { } //~ ERROR non-exhaustive patterns | ^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/issue-3096-2.rs:5:11 - | -LL | match x { } //~ ERROR non-exhaustive patterns - | ^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/issues/issue-31561.stderr b/src/test/ui/issues/issue-31561.stderr index c95fc36cea6e8..246137aeee05c 100644 --- a/src/test/ui/issues/issue-31561.stderr +++ b/src/test/ui/issues/issue-31561.stderr @@ -1,8 +1,15 @@ error[E0005]: refutable pattern in local binding: `Bar` not covered --> $DIR/issue-31561.rs:8:9 | -LL | let Thing::Foo(y) = Thing::Foo(1); - | ^^^^^^^^^^^^^ pattern `Bar` not covered +LL | / enum Thing { +LL | | Foo(u8), +LL | | Bar, +LL | | Baz +LL | | } + | |_- `Thing` defined here +... +LL | let Thing::Foo(y) = Thing::Foo(1); + | ^^^^^^^^^^^^^ pattern `Bar` not covered error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3601.stderr b/src/test/ui/issues/issue-3601.stderr index 0b5242ee528dd..85b534434342b 100644 --- a/src/test/ui/issues/issue-3601.stderr +++ b/src/test/ui/issues/issue-3601.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `_` not covered | LL | box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns | ^^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/issues/issue-39362.stderr b/src/test/ui/issues/issue-39362.stderr index 06385127e94fe..55cd14a5c1e08 100644 --- a/src/test/ui/issues/issue-39362.stderr +++ b/src/test/ui/issues/issue-39362.stderr @@ -1,8 +1,15 @@ error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered --> $DIR/issue-39362.rs:10:11 | -LL | match f { - | ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered +LL | / enum Foo { +LL | | Bar { bar: Bar, id: usize } +LL | | } + | |_- `Foo` defined here +... +LL | match f { + | ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/issues/issue-4321.stderr b/src/test/ui/issues/issue-4321.stderr index 7817fdcbce99c..731e63fbb2b04 100644 --- a/src/test/ui/issues/issue-4321.stderr +++ b/src/test/ui/issues/issue-4321.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered | LL | println!("foo {:}", match tup { //~ ERROR non-exhaustive patterns: `(true, false)` not covered | ^^^ pattern `(true, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/match/match-argm-statics-2.stderr b/src/test/ui/match/match-argm-statics-2.stderr index 3e6f22ab87513..8c54e030823af 100644 --- a/src/test/ui/match/match-argm-statics-2.stderr +++ b/src/test/ui/match/match-argm-statics-2.stderr @@ -3,18 +3,30 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered | LL | match (true, false) { | ^^^^^^^^^^^^^ pattern `(true, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered --> $DIR/match-argm-statics-2.rs:29:11 | LL | match Some(Some(North)) { | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered --> $DIR/match-argm-statics-2.rs:48:11 | -LL | match (Foo { bar: Some(North), baz: NewBool(true) }) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered +LL | / struct Foo { +LL | | bar: Option, +LL | | baz: NewBool +LL | | } + | |_- `Foo` defined here +... +LL | match (Foo { bar: Some(North), baz: NewBool(true) }) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 3 previous errors diff --git a/src/test/ui/match/match-byte-array-patterns-2.stderr b/src/test/ui/match/match-byte-array-patterns-2.stderr index 4030cd39448a0..83dbecfcac657 100644 --- a/src/test/ui/match/match-byte-array-patterns-2.stderr +++ b/src/test/ui/match/match-byte-array-patterns-2.stderr @@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `&[_, _, _, _]` not covered | LL | match buf { //~ ERROR non-exhaustive | ^^^ pattern `&[_, _, _, _]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 3 more not covered --> $DIR/match-byte-array-patterns-2.rs:10:11 | LL | match buf { //~ ERROR non-exhaustive | ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 3 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/match/match-non-exhaustive.stderr b/src/test/ui/match/match-non-exhaustive.stderr index ab5ab18c3283a..9921e4f63b641 100644 --- a/src/test/ui/match/match-non-exhaustive.stderr +++ b/src/test/ui/match/match-non-exhaustive.stderr @@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `-2147483648i32..=0i32` and `2i32..=21474 | LL | match 0 { 1 => () } //~ ERROR non-exhaustive patterns | ^ patterns `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `_` not covered --> $DIR/match-non-exhaustive.rs:3:11 | LL | match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns | ^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/match/match-privately-empty.stderr b/src/test/ui/match/match-privately-empty.stderr index 23ca64e50af78..f79d180a1b8b5 100644 --- a/src/test/ui/match/match-privately-empty.stderr +++ b/src/test/ui/match/match-privately-empty.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not co | LL | match private::DATA { | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/match/match-slice-patterns.stderr b/src/test/ui/match/match-slice-patterns.stderr index 2b817498aba9f..24769db34c932 100644 --- a/src/test/ui/match/match-slice-patterns.stderr +++ b/src/test/ui/match/match-slice-patterns.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `&[_, Some(_), None, _]` not covered | LL | match list { | ^^^^ pattern `&[_, Some(_), None, _]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/missing/missing-items/issue-40221.stderr b/src/test/ui/missing/missing-items/issue-40221.stderr index 437fb7bbc3131..9e4ce7c81b70e 100644 --- a/src/test/ui/missing/missing-items/issue-40221.stderr +++ b/src/test/ui/missing/missing-items/issue-40221.stderr @@ -1,8 +1,16 @@ error[E0004]: non-exhaustive patterns: `C(QA)` not covered --> $DIR/issue-40221.rs:11:11 | -LL | match proto { //~ ERROR non-exhaustive patterns - | ^^^^^ pattern `C(QA)` not covered +LL | / enum P { +LL | | C(PC), + | | - not covered +LL | | } + | |_- `P` defined here +... +LL | match proto { //~ ERROR non-exhaustive patterns + | ^^^^^ pattern `C(QA)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr index 2e285afb3804e..03215f72ebcd4 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr +++ b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `_` not covered | LL | match 0.0 { //~ ERROR non-exhaustive patterns | ^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match-nested.stderr b/src/test/ui/non-exhaustive/non-exhaustive-match-nested.stderr index b2551c8dcf2ae..d5beac4b71633 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-match-nested.stderr +++ b/src/test/ui/non-exhaustive/non-exhaustive-match-nested.stderr @@ -3,12 +3,22 @@ error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered | LL | match (l1, l2) { //~ ERROR non-exhaustive patterns: `(Some(&[]), Err(_))` not covered | ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `A(C)` not covered --> $DIR/non-exhaustive-match-nested.rs:17:11 | +LL | enum T { A(U), B } + | ------------------ + | | | + | | not covered + | `T` defined here +... LL | match x { //~ ERROR non-exhaustive patterns: `A(C)` not covered | ^ pattern `A(C)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr index 8d2a73b2c6dcc..112e18432b440 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr +++ b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr @@ -1,50 +1,78 @@ error[E0004]: non-exhaustive patterns: `A` not covered --> $DIR/non-exhaustive-match.rs:8:11 | +LL | enum T { A, B } + | --------------- + | | | + | | not covered + | `T` defined here +... LL | match x { T::B => { } } //~ ERROR non-exhaustive patterns: `A` not covered | ^ pattern `A` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `false` not covered --> $DIR/non-exhaustive-match.rs:9:11 | LL | match true { //~ ERROR non-exhaustive patterns: `false` not covered | ^^^^ pattern `false` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(_)` not covered --> $DIR/non-exhaustive-match.rs:12:11 | LL | match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered | ^^^^^^^^ pattern `Some(_)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered --> $DIR/non-exhaustive-match.rs:15:11 | LL | match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` | ^^^^^^^^^ patterns `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(A, A)` not covered --> $DIR/non-exhaustive-match.rs:19:11 | LL | match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` not covered | ^^^^^^^^^^^^ pattern `(A, A)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `B` not covered --> $DIR/non-exhaustive-match.rs:23:11 | +LL | enum T { A, B } + | --------------- + | | | + | | not covered + | `T` defined here +... LL | match T::A { //~ ERROR non-exhaustive patterns: `B` not covered | ^^^^ pattern `B` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[]` not covered --> $DIR/non-exhaustive-match.rs:34:11 | LL | match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered | ^^^^ pattern `[]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered --> $DIR/non-exhaustive-match.rs:47:11 | LL | match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered | ^^^^ pattern `[_, _, _, _]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 8 previous errors diff --git a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.stderr b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.stderr index d3a06e7b4b6f8..a0b497dd4c0ba 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.stderr +++ b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.stderr @@ -1,44 +1,94 @@ error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered --> $DIR/non-exhaustive-pattern-witness.rs:9:11 | -LL | match (Foo { first: true, second: None }) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered +LL | / struct Foo { +LL | | first: bool, +LL | | second: Option<[usize; 4]> +LL | | } + | |_- `Foo` defined here +... +LL | match (Foo { first: true, second: None }) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Red` not covered --> $DIR/non-exhaustive-pattern-witness.rs:25:11 | -LL | match Color::Red { - | ^^^^^^^^^^ pattern `Red` not covered +LL | / enum Color { +LL | | Red, + | | --- not covered +LL | | Green, +LL | | CustomRGBA { a: bool, r: u8, g: u8, b: u8 } +LL | | } + | |_- `Color` defined here +... +LL | match Color::Red { + | ^^^^^^^^^^ pattern `Red` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered --> $DIR/non-exhaustive-pattern-witness.rs:37:11 | -LL | match Direction::North { - | ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered +LL | / enum Direction { +LL | | North, East, South, West + | | ---- ----- ---- not covered + | | | | + | | | not covered + | | not covered +LL | | } + | |_- `Direction` defined here +... +LL | match Direction::North { + | ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered --> $DIR/non-exhaustive-pattern-witness.rs:48:11 | -LL | match ExcessiveEnum::First { - | ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered +LL | / enum ExcessiveEnum { +LL | | First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth +LL | | } + | |_- `ExcessiveEnum` defined here +... +LL | match ExcessiveEnum::First { + | ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered --> $DIR/non-exhaustive-pattern-witness.rs:56:11 | -LL | match Color::Red { - | ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered +LL | / enum Color { +LL | | Red, +LL | | Green, +LL | | CustomRGBA { a: bool, r: u8, g: u8, b: u8 } + | | ---------- not covered +LL | | } + | |_- `Color` defined here +... +LL | match Color::Red { + | ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered --> $DIR/non-exhaustive-pattern-witness.rs:72:11 | LL | match *x { | ^^ pattern `[Second(true), Second(false)]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((), false)` not covered --> $DIR/non-exhaustive-pattern-witness.rs:85:11 | LL | match ((), false) { | ^^^^^^^^^^^ pattern `((), false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 7 previous errors diff --git a/src/test/ui/precise_pointer_size_matching.stderr b/src/test/ui/precise_pointer_size_matching.stderr index 4acbec6c7ff1a..a8906a43003ae 100644 --- a/src/test/ui/precise_pointer_size_matching.stderr +++ b/src/test/ui/precise_pointer_size_matching.stderr @@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `$ISIZE_MIN..=-6isize` and `21isize..=$IS | LL | match 0isize { //~ ERROR non-exhaustive patterns | ^^^^^^ patterns `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=$USIZE_MAX` not covered --> $DIR/precise_pointer_size_matching.rs:29:11 | LL | match 0usize { //~ ERROR non-exhaustive patterns | ^^^^^^ patterns `0usize` and `21usize..=$USIZE_MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr index 1dfad0d31896c..e24c8f1555901 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered | LL | match sl { //~ ERROR non-exhaustive patterns | ^^ pattern `&[]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr index acce9779067a6..b5c1a4ebba4ac 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `_` not covered | LL | match enum_unit { | ^^^^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/structs/struct-like-enum-nonexhaustive.stderr b/src/test/ui/structs/struct-like-enum-nonexhaustive.stderr index d651ea0b4e2d7..0aa85eb7253e8 100644 --- a/src/test/ui/structs/struct-like-enum-nonexhaustive.stderr +++ b/src/test/ui/structs/struct-like-enum-nonexhaustive.stderr @@ -1,8 +1,17 @@ error[E0004]: non-exhaustive patterns: `B { x: Some(_) }` not covered --> $DIR/struct-like-enum-nonexhaustive.rs:8:11 | -LL | match x { //~ ERROR non-exhaustive patterns - | ^ pattern `B { x: Some(_) }` not covered +LL | / enum A { +LL | | B { x: Option }, + | | - not covered +LL | | C +LL | | } + | |_- `A` defined here +... +LL | match x { //~ ERROR non-exhaustive patterns + | ^ pattern `B { x: Some(_) }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/tuple/tuple-struct-nonexhaustive.stderr b/src/test/ui/tuple/tuple-struct-nonexhaustive.stderr index 8d627fc2a8d72..58d0862be6d21 100644 --- a/src/test/ui/tuple/tuple-struct-nonexhaustive.stderr +++ b/src/test/ui/tuple/tuple-struct-nonexhaustive.stderr @@ -1,8 +1,13 @@ error[E0004]: non-exhaustive patterns: `Foo(_, _)` not covered --> $DIR/tuple-struct-nonexhaustive.rs:5:11 | +LL | struct Foo(isize, isize); + | ------------------------- `Foo` defined here +... LL | match x { //~ ERROR non-exhaustive | ^ pattern `Foo(_, _)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to previous error diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr index 63819bf949bd3..2424252af2ad3 100644 --- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr +++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr @@ -1,8 +1,16 @@ error[E0005]: refutable pattern in local binding: `A(_)` not covered --> $DIR/uninhabited-irrefutable.rs:27:9 | -LL | let Foo::D(_y) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered - | ^^^^^^^^^^ pattern `A(_)` not covered +LL | / enum Foo { +LL | | A(foo::SecretlyEmpty), +LL | | B(foo::NotSoSecretlyEmpty), +LL | | C(NotSoSecretlyEmpty), +LL | | D(u32), +LL | | } + | |_- `Foo` defined here +... +LL | let Foo::D(_y) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered + | ^^^^^^^^^^ pattern `A(_)` not covered error: aborting due to previous error diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index b88dcc9aea435..fec95ca149431 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered | LL | let _ = match x { //~ ERROR non-exhaustive | ^ pattern `Err(_)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `&Void` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:10:19 @@ -10,11 +12,7 @@ error[E0004]: non-exhaustive patterns: type `&Void` is non-empty LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/uninhabited-matches-feature-gated.rs:10:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:13:19 @@ -22,11 +20,7 @@ error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/uninhabited-matches-feature-gated.rs:13:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:16:19 @@ -34,23 +28,23 @@ error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ | -help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - --> $DIR/uninhabited-matches-feature-gated.rs:16:19 - | -LL | let _ = match x {}; //~ ERROR non-exhaustive - | ^ + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_]` not covered --> $DIR/uninhabited-matches-feature-gated.rs:19:19 | LL | let _ = match x { //~ ERROR non-exhaustive | ^ pattern `&[_]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Err(_)` not covered --> $DIR/uninhabited-matches-feature-gated.rs:27:19 | LL | let _ = match x { //~ ERROR non-exhaustive | ^ pattern `Err(_)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0005]: refutable pattern in local binding: `Err(_)` not covered --> $DIR/uninhabited-matches-feature-gated.rs:32:9 From 509bb0acba1de4ca9b766efd432a824b798ce6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 11 Feb 2019 11:22:46 -0800 Subject: [PATCH 2/3] Use anonymous explicit lifetimes --- src/librustc_mir/hair/pattern/check_match.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 96709e2ac0453..c92f3d4e51bf4 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -484,7 +484,7 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>( err.span_label(sp, format!("`{}` defined here", scrut_ty)); } } - let patterns = witnesses.iter().map(|p| (**p).clone()).collect::>(); + let patterns = witnesses.iter().map(|p| (**p).clone()).collect::>>(); if patterns.len() < 4 { for sp in maybe_point_at_variant(cx, &scrut_ty.sty, patterns.as_slice()) { err.span_label(sp, "not covered"); @@ -504,13 +504,13 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>( fn maybe_point_at_variant( cx: &mut MatchCheckCtxt<'a, 'tcx>, sty: &TyKind<'tcx>, - patterns: &[Pattern], + patterns: &[Pattern<'_>], ) -> Vec { let mut covered = vec![]; if let ty::Adt(def, _) = sty { // Don't point at the variants if they are too many to avoid visual clutter for pattern in patterns { - let pk: &PatternKind = &pattern.kind; + let pk: &PatternKind<'_> = &pattern.kind; if let PatternKind::Variant { adt_def, variant_index, subpatterns, .. } = pk { if adt_def.did == def.did { let sp = def.variants[*variant_index].ident.span; From d651281a71b7d31947e33383dcb2a5647827e0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 2 Mar 2019 16:44:00 -0800 Subject: [PATCH 3/3] Reword error message --- src/librustc_mir/hair/pattern/check_match.rs | 26 ++++++++++++++------ src/test/ui/error-codes/E0004-2.stderr | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index c92f3d4e51bf4..f56d28d6f864e 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -217,7 +217,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { if def.variants.len() < 4 && !def.variants.is_empty() { // keep around to point at the definition of non-covered variants missing_variants = def.variants.iter() - .map(|variant| variant.ident.span) + .map(|variant| variant.ident) .collect(); } def.variants.is_empty() @@ -227,10 +227,19 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { }; if !scrutinee_is_uninhabited { // We know the type is inhabited, so this must be wrong - let mut err = create_e0004(self.tcx.sess, scrut.span, format!( - "non-exhaustive patterns: type `{}` is non-empty", - pat_ty, - )); + let mut err = create_e0004( + self.tcx.sess, + scrut.span, + format!("non-exhaustive patterns: {}", match missing_variants.len() { + 0 => format!("type `{}` is non-empty", pat_ty), + 1 => format!( + "pattern `{}` of type `{}` is not handled", + missing_variants[0].name, + pat_ty, + ), + _ => format!("multiple patterns of type `{}` are not handled", pat_ty), + }), + ); err.help("ensure that all possible cases are being handled, \ possibly by adding wildcards or more match arms"); if let Some(sp) = def_span { @@ -238,7 +247,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } // point at the definition of non-covered enum variants for variant in &missing_variants { - err.span_label(*variant, "variant not covered"); + err.span_label(variant.span, "variant not covered"); } err.emit(); } @@ -508,7 +517,8 @@ fn maybe_point_at_variant( ) -> Vec { let mut covered = vec![]; if let ty::Adt(def, _) = sty { - // Don't point at the variants if they are too many to avoid visual clutter + // Don't point at variants that have already been covered due to other patterns to avoid + // visual clutter for pattern in patterns { let pk: &PatternKind<'_> = &pattern.kind; if let PatternKind::Variant { adt_def, variant_index, subpatterns, .. } = pk { @@ -526,7 +536,7 @@ fn maybe_point_at_variant( ); } } - if let PatternKind::Leaf{ subpatterns } = pk { + if let PatternKind::Leaf { subpatterns } = pk { let subpatterns = subpatterns.iter() .map(|field_pattern| field_pattern.pattern.clone()) .collect::>(); diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index 94e38cf26aa4d..c8732852a71ee 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type `std::option::Option` is non-empty +error[E0004]: non-exhaustive patterns: multiple patterns of type `std::option::Option` are not handled --> $DIR/E0004-2.rs:4:11 | LL | match x { } //~ ERROR E0004