diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index b0be74626209..e886c4ea443e 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -169,20 +169,14 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { // Then, if the match has no arms, check whether the scrutinee // is uninhabited. let pat_ty = self.tables.node_type(scrut.hir_id); - let module = self.tcx.hir().get_module_parent(scrut.hir_id); - let mut def_span = None; - let mut missing_variants = vec![]; if inlined_arms.is_empty() { let scrutinee_is_visibly_uninhabited = if self.tcx.features().exhaustive_patterns { + let module = self.tcx.hir().get_module_parent(scrut.hir_id); self.tcx.is_ty_uninhabited_from(module, pat_ty) } else { match pat_ty.kind { ty::Never => true, ty::Adt(def, _) => { - def_span = self.tcx.hir().span_if_local(def.did); - missing_variants = - def.variants.iter().map(|variant| variant.ident).collect(); - def.variants.is_empty() && !cx.is_foreign_non_exhaustive_enum(pat_ty) } _ => false, @@ -190,6 +184,14 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { }; if !scrutinee_is_visibly_uninhabited { // We know the type is inhabited, so this must be wrong + let (def_span, missing_variants) = match pat_ty.kind { + ty::Adt(def, _) => ( + self.tcx.hir().span_if_local(def.did), + def.variants.iter().map(|variant| variant.ident).collect(), + ), + _ => (None, vec![]), + }; + let mut err = create_e0004( self.tcx.sess, scrut.span, diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs index 11eae2af9c95..b568057ed1e5 100644 --- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs +++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs @@ -25,7 +25,7 @@ fn match_on_uninhab() { } match uninhab_union() { - //~^ ERROR non-exhaustive patterns: type `Foo` is non-empty + //~^ ERROR non-exhaustive patterns: pattern `Foo` of type `Foo` is not handled } } diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr index 792ab6f59a43..acf926e9a832 100644 --- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr +++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr @@ -6,11 +6,19 @@ 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 +error[E0004]: non-exhaustive patterns: pattern `Foo` of type `Foo` is not handled --> $DIR/always-inhabited-union-ref.rs:27:11 | -LL | match uninhab_union() { - | ^^^^^^^^^^^^^^^ +LL | pub union Foo { + | - --- variant not covered + | _| + | | +LL | | foo: !, +LL | | } + | |_- `Foo` defined here +... +LL | match uninhab_union() { + | ^^^^^^^^^^^^^^^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs index 3d01c31f0364..01671eb5ce36 100644 --- a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs +++ b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs @@ -3,15 +3,15 @@ #![deny(unreachable_patterns)] enum Foo {} -struct NonEmptyStruct(bool); -enum NonEmptyEnum1 { - Foo(bool), +struct NonEmptyStruct(bool); //~ `NonEmptyStruct` defined here +enum NonEmptyEnum1 { //~ `NonEmptyEnum1` defined here + Foo(bool), //~ variant not covered } -enum NonEmptyEnum2 { - Foo(bool), - Bar, +enum NonEmptyEnum2 { //~ `NonEmptyEnum2` defined here + Foo(bool), //~ variant not covered + Bar, //~ variant not covered } -enum NonEmptyEnum5 { +enum NonEmptyEnum5 { //~ `NonEmptyEnum5` defined here V1, V2, V3, V4, V5, } @@ -35,11 +35,11 @@ fn main() { match 0u8 {} //~^ ERROR type `u8` is non-empty match NonEmptyStruct(true) {} - //~^ ERROR type `NonEmptyStruct` is non-empty + //~^ ERROR pattern `NonEmptyStruct` of type `NonEmptyStruct` is not handled match NonEmptyEnum1::Foo(true) {} - //~^ ERROR type `NonEmptyEnum1` is non-empty + //~^ ERROR pattern `Foo` of type `NonEmptyEnum1` is not handled match NonEmptyEnum2::Foo(true) {} - //~^ ERROR type `NonEmptyEnum2` is non-empty + //~^ ERROR multiple patterns of type `NonEmptyEnum2` are not handled match NonEmptyEnum5::V1 {} - //~^ ERROR type `NonEmptyEnum5` is non-empty + //~^ ERROR multiple patterns of type `NonEmptyEnum5` are not handled } diff --git a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr index 19c16dba0002..d126b9185d10 100644 --- a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr @@ -30,35 +30,60 @@ LL | match 0u8 {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `NonEmptyStruct` is non-empty +error[E0004]: non-exhaustive patterns: pattern `NonEmptyStruct` of type `NonEmptyStruct` is not handled --> $DIR/match-empty-exhaustive_patterns.rs:37:11 | +LL | struct NonEmptyStruct(bool); + | ---------------------------- + | | | + | | variant not covered + | `NonEmptyStruct` defined here +... LL | match NonEmptyStruct(true) {} | ^^^^^^^^^^^^^^^^^^^^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `NonEmptyEnum1` is non-empty +error[E0004]: non-exhaustive patterns: pattern `Foo` of type `NonEmptyEnum1` is not handled --> $DIR/match-empty-exhaustive_patterns.rs:39:11 | -LL | match NonEmptyEnum1::Foo(true) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / enum NonEmptyEnum1 { +LL | | Foo(bool), + | | --- variant not covered +LL | | } + | |_- `NonEmptyEnum1` defined here +... +LL | match NonEmptyEnum1::Foo(true) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `NonEmptyEnum2` is non-empty +error[E0004]: non-exhaustive patterns: multiple patterns of type `NonEmptyEnum2` are not handled --> $DIR/match-empty-exhaustive_patterns.rs:41:11 | -LL | match NonEmptyEnum2::Foo(true) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / enum NonEmptyEnum2 { +LL | | Foo(bool), + | | --- variant not covered +LL | | Bar, + | | --- variant not covered +LL | | } + | |_- `NonEmptyEnum2` defined here +... +LL | match NonEmptyEnum2::Foo(true) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `NonEmptyEnum5` is non-empty +error[E0004]: non-exhaustive patterns: multiple patterns of type `NonEmptyEnum5` are not handled --> $DIR/match-empty-exhaustive_patterns.rs:43:11 | -LL | match NonEmptyEnum5::V1 {} - | ^^^^^^^^^^^^^^^^^ +LL | / enum NonEmptyEnum5 { +LL | | V1, V2, V3, V4, V5, +LL | | } + | |_- `NonEmptyEnum5` defined here +... +LL | match NonEmptyEnum5::V1 {} + | ^^^^^^^^^^^^^^^^^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr index 2c2e54293417..42a99367fa97 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedEnum` is non-empty +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `uninhabited::IndirectUninhabitedEnum` is not handled --> $DIR/indirect_match_with_exhaustive_patterns.rs:22:11 | LL | match x {} @@ -6,7 +6,7 @@ LL | match x {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedStruct` is non-empty +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `uninhabited::IndirectUninhabitedStruct` is not handled --> $DIR/indirect_match_with_exhaustive_patterns.rs:26:11 | LL | match x {} @@ -14,7 +14,7 @@ LL | match x {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedTupleStruct` is non-empty +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `uninhabited::IndirectUninhabitedTupleStruct` is not handled --> $DIR/indirect_match_with_exhaustive_patterns.rs:30:11 | LL | match x {} @@ -22,7 +22,7 @@ LL | match x {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedVariants` is non-empty +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `uninhabited::IndirectUninhabitedVariants` is not handled --> $DIR/indirect_match_with_exhaustive_patterns.rs:36:11 | LL | match x {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr index 3b56c6890710..113b7db1c6e6 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr @@ -6,7 +6,7 @@ LL | match x {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedStruct` is non-empty +error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `uninhabited::UninhabitedStruct` is not handled --> $DIR/match_with_exhaustive_patterns.rs:25:11 | LL | match x {} @@ -14,7 +14,7 @@ LL | match x {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedTupleStruct` is non-empty +error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `uninhabited::UninhabitedTupleStruct` is not handled --> $DIR/match_with_exhaustive_patterns.rs:29:11 | LL | match x {} @@ -22,7 +22,7 @@ LL | match x {} | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedVariants` is non-empty +error[E0004]: non-exhaustive patterns: multiple patterns of type `uninhabited::UninhabitedVariants` are not handled --> $DIR/match_with_exhaustive_patterns.rs:33:11 | LL | match x {}