From 0db087e6840cc865bcf8be09ff940f2ac13341ac Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 01:15:26 +0100 Subject: Add uninhabitedness tests w/ `#[non_exhaustive]`. This commit adds tests checking that uninhabited non-exhaustive types are considered inhabited when used in another crate. --- .../auxiliary/uninhabited.rs | 25 ++++++++ src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs | 59 ++++++++++++++++++ .../uninhabited_same_crate.rs | 71 ++++++++++++++++++++++ .../uninhabited_same_crate.stderr | 38 ++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs new file mode 100644 index 00000000000..a4b936e376d --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs @@ -0,0 +1,25 @@ +#![crate_type = "rlib"] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs new file mode 100644 index 00000000000..97061310d19 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs @@ -0,0 +1,59 @@ +// aux-build:uninhabited.rs +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] + +extern crate uninhabited; + +use uninhabited::{ + PartiallyInhabitedVariants, + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are not considered uninhabited from extern crates. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // This line would normally error. + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // This line would normally error. + None => (), + } + + // This line would normally error. + while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { + } + + while let Some(_x) = uninhabited_struct() { // This line would normally error. + } + + while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs new file mode 100644 index 00000000000..302a35cab5f --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs @@ -0,0 +1,71 @@ +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are still considered uninhabited. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + //~^ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr new file mode 100644 index 00000000000..942f004c3cf --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr @@ -0,0 +1,38 @@ +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:53:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/uninhabited_same_crate.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:58:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:62:15 + | +LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:66:15 + | +LL | while let Some(_x) = uninhabited_struct() { + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:69:15 + | +LL | while let Some(_x) = uninhabited_tuple_struct() { + | ^^^^^^^^ + +error: aborting due to 5 previous errors + -- cgit 1.4.1-3-g733a5 From 0d034a2e4dd9418fa41aba4ebdd1ebc31a08c9e9 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 01:17:26 +0100 Subject: Fix inhabitedness of non-exhaustive variants. This commit ensures that non-exhaustive variants are considered inhabited when used in extern crates. --- src/librustc/ty/inhabitedness/mod.rs | 11 ++++++++--- src/librustc_mir/hair/pattern/_match.rs | 27 +++++++++++++++++++++++---- src/test/ui/pattern/const-pat-ice.stderr | 2 +- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 197d3325f51..2fc07fb20bf 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -134,9 +134,14 @@ impl<'a, 'gcx, 'tcx> VariantDef { AdtKind::Enum => true, AdtKind::Struct => false, }; - DefIdForest::union(tcx, self.fields.iter().map(|f| { - f.uninhabited_from(tcx, substs, is_enum) - })) + // Non-exhaustive variants from other crates are always considered inhabited. + if self.is_field_list_non_exhaustive() && !self.def_id.is_local() { + DefIdForest::empty() + } else { + DefIdForest::union(tcx, self.fields.iter().map(|f| { + f.uninhabited_from(tcx, substs, is_enum) + })) + } } } diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index edd36abc0b8..fd4416fc2b7 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -388,6 +388,18 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { } } + fn is_non_exhaustive_variant<'p>(&self, pattern: &'p Pattern<'tcx>) -> bool + where 'a: 'p + { + match *pattern.kind { + PatternKind::Variant { adt_def, variant_index, .. } => { + let ref variant = adt_def.variants[variant_index]; + variant.is_field_list_non_exhaustive() + } + _ => false, + } + } + fn is_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool { match ty.sty { ty::Adt(adt_def, ..) => adt_def.is_variant_list_non_exhaustive(), @@ -1097,10 +1109,17 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v[0]); if let Some(constructors) = pat_constructors(cx, v[0], pcx) { - debug!("is_useful - expanding constructors: {:#?}", constructors); - split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c| - is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) - ).find(|result| result.is_useful()).unwrap_or(NotUseful) + let is_declared_nonexhaustive = cx.is_non_exhaustive_variant(v[0]) && !cx.is_local(pcx.ty); + debug!("is_useful - expanding constructors: {:#?}, is_declared_nonexhaustive: {:?}", + constructors, is_declared_nonexhaustive); + + if is_declared_nonexhaustive { + Useful + } else { + split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c| + is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) + ).find(|result| result.is_useful()).unwrap_or(NotUseful) + } } else { debug!("is_useful - expanding wildcard"); diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 261e95229a7..260c2e04d74 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,4 +1,4 @@ -thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1071:5 +thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1083:5 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic -- cgit 1.4.1-3-g733a5 From 8838b9130e2f6551077f432dddd5a8077ae4d2e1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 11:03:06 +0100 Subject: Fix uninhabitedness of non-exhaustive enums. This commit ensures that non-exhaustive enums are considered inhabited when used in extern crates. --- src/librustc/ty/inhabitedness/mod.rs | 11 +++- src/librustc_mir/hair/pattern/check_match.rs | 6 +- src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs | 55 ++++++----------- .../ui/rfc-2008-non-exhaustive/uninhabited.stderr | 47 ++++++++++++++ .../rfc-2008-non-exhaustive/uninhabited_match.rs | 19 ++++++ .../uninhabited_match.stderr | 11 ++++ .../uninhabited_match_same_crate.rs | 18 ++++++ .../uninhabited_match_with_exhaustive_patterns.rs | 22 +++++++ ...inhabited_match_with_exhaustive_patterns.stderr | 11 ++++ ...ed_match_with_exhaustive_patterns_same_crate.rs | 21 +++++++ .../uninhabited_patterns.rs | 59 ++++++++++++++++++ .../uninhabited_patterns_same_crate.rs | 71 ++++++++++++++++++++++ .../uninhabited_patterns_same_crate.stderr | 38 ++++++++++++ .../uninhabited_same_crate.rs | 55 +++++------------ .../uninhabited_same_crate.stderr | 63 +++++++++++-------- 15 files changed, 398 insertions(+), 109 deletions(-) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 2fc07fb20bf..be1d973c2cd 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -113,9 +113,14 @@ impl<'a, 'gcx, 'tcx> AdtDef { tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest { - DefIdForest::intersection(tcx, self.variants.iter().map(|v| { - v.uninhabited_from(tcx, substs, self.adt_kind()) - })) + // Non-exhaustive ADTs from other crates are always considered inhabited. + if self.is_variant_list_non_exhaustive() && !self.did.is_local() { + DefIdForest::empty() + } else { + DefIdForest::intersection(tcx, self.variants.iter().map(|v| { + v.uninhabited_from(tcx, substs, self.adt_kind()) + })) + } } } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 1a7266859ad..8c7155e1df3 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -208,7 +208,11 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { .map(|variant| variant.ident) .collect(); } - def.variants.is_empty() + + let is_non_exhaustive_and_non_local = + def.is_variant_list_non_exhaustive() && !def.did.is_local(); + + !(is_non_exhaustive_and_non_local) && def.variants.is_empty() }, _ => false } diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs index 97061310d19..80b9dc4c1c3 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs @@ -1,59 +1,38 @@ // aux-build:uninhabited.rs -// compile-pass -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] +#![feature(never_type)] extern crate uninhabited; use uninhabited::{ - PartiallyInhabitedVariants, UninhabitedEnum, UninhabitedStruct, UninhabitedTupleStruct, UninhabitedVariants, }; -fn uninhabited_enum() -> Option { - None -} +// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never +// type can. -fn uninhabited_variant() -> Option { - None -} +struct A; -fn partially_inhabited_variant() -> PartiallyInhabitedVariants { - PartiallyInhabitedVariants::Tuple(3) +fn can_coerce_never_type_to_anything(x: !) -> A { + x } -fn uninhabited_struct() -> Option { - None +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x //~ ERROR mismatched types } -fn uninhabited_tuple_struct() -> Option { - None +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x //~ ERROR mismatched types } -// This test checks that non-exhaustive types that would normally be considered uninhabited within -// the defining crate are not considered uninhabited from extern crates. - -fn main() { - match uninhabited_enum() { - Some(_x) => (), // This line would normally error. - None => (), - } - - match uninhabited_variant() { - Some(_x) => (), // This line would normally error. - None => (), - } - - // This line would normally error. - while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { - } - - while let Some(_x) = uninhabited_struct() { // This line would normally error. - } +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x //~ ERROR mismatched types +} - while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. - } +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x //~ ERROR mismatched types } + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr new file mode 100644 index 00000000000..490a6c10117 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:23:5 + | +LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `uninhabited::UninhabitedEnum` + | + = note: expected type `A` + found type `uninhabited::UninhabitedEnum` + +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:27:5 + | +LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `uninhabited::UninhabitedTupleStruct` + | + = note: expected type `A` + found type `uninhabited::UninhabitedTupleStruct` + +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:31:5 + | +LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `uninhabited::UninhabitedStruct` + | + = note: expected type `A` + found type `uninhabited::UninhabitedStruct` + +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:35:5 + | +LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `uninhabited::UninhabitedVariants` + | + = note: expected type `A` + found type `uninhabited::UninhabitedVariants` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs new file mode 100644 index 00000000000..0166b2e46cb --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs @@ -0,0 +1,19 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr new file mode 100644 index 00000000000..3000e1b0930 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty + --> $DIR/uninhabited_match.rs:16:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs new file mode 100644 index 00000000000..d8b1c3810f3 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs @@ -0,0 +1,18 @@ +// compile-pass +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs new file mode 100644 index 00000000000..d82010158cc --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs @@ -0,0 +1,22 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} 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 new file mode 100644 index 00000000000..73d9e689b55 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty + --> $DIR/uninhabited_match_with_exhaustive_patterns.rs:19:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 00000000000..da814a70a75 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,21 @@ +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs new file mode 100644 index 00000000000..97061310d19 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs @@ -0,0 +1,59 @@ +// aux-build:uninhabited.rs +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] + +extern crate uninhabited; + +use uninhabited::{ + PartiallyInhabitedVariants, + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are not considered uninhabited from extern crates. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // This line would normally error. + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // This line would normally error. + None => (), + } + + // This line would normally error. + while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { + } + + while let Some(_x) = uninhabited_struct() { // This line would normally error. + } + + while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs new file mode 100644 index 00000000000..302a35cab5f --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs @@ -0,0 +1,71 @@ +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are still considered uninhabited. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + //~^ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr new file mode 100644 index 00000000000..8e995632b2f --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr @@ -0,0 +1,38 @@ +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:53:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/uninhabited_patterns_same_crate.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:58:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:62:15 + | +LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:66:15 + | +LL | while let Some(_x) = uninhabited_struct() { + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:69:15 + | +LL | while let Some(_x) = uninhabited_tuple_struct() { + | ^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs index 302a35cab5f..803a542f8aa 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs @@ -1,5 +1,3 @@ -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] #![feature(never_type)] #![feature(non_exhaustive)] @@ -20,52 +18,29 @@ pub enum UninhabitedVariants { #[non_exhaustive] Struct { x: ! } } -pub enum PartiallyInhabitedVariants { - Tuple(u8), - #[non_exhaustive] Struct { x: ! } -} +struct A; -fn uninhabited_enum() -> Option { - None -} +// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce +// to any type, as the never type can. -fn uninhabited_variant() -> Option { - None +fn can_coerce_never_type_to_anything(x: !) -> A { + x } -fn partially_inhabited_variant() -> PartiallyInhabitedVariants { - PartiallyInhabitedVariants::Tuple(3) +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x //~ ERROR mismatched types } -fn uninhabited_struct() -> Option { - None +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x //~ ERROR mismatched types } -fn uninhabited_tuple_struct() -> Option { - None +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x //~ ERROR mismatched types } -// This test checks that non-exhaustive types that would normally be considered uninhabited within -// the defining crate are still considered uninhabited. - -fn main() { - match uninhabited_enum() { - Some(_x) => (), //~ ERROR unreachable pattern - None => (), - } - - match uninhabited_variant() { - Some(_x) => (), //~ ERROR unreachable pattern - None => (), - } - - while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { - //~^ ERROR unreachable pattern - } - - while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern - } - - while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern - } +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x //~ ERROR mismatched types } + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr index 942f004c3cf..ea79e7105d5 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr @@ -1,38 +1,47 @@ -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:53:9 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:31:5 | -LL | Some(_x) => (), - | ^^^^^^^^ +LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `UninhabitedEnum` | -note: lint level defined here - --> $DIR/uninhabited_same_crate.rs:1:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ + = note: expected type `A` + found type `UninhabitedEnum` -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:58:9 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:35:5 | -LL | Some(_x) => (), - | ^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:62:15 +LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `UninhabitedTupleStruct` | -LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected type `A` + found type `UninhabitedTupleStruct` -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:66:15 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:39:5 | -LL | while let Some(_x) = uninhabited_struct() { - | ^^^^^^^^ +LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `UninhabitedStruct` + | + = note: expected type `A` + found type `UninhabitedStruct` -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:69:15 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:43:5 + | +LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `UninhabitedVariants` | -LL | while let Some(_x) = uninhabited_tuple_struct() { - | ^^^^^^^^ + = note: expected type `A` + found type `UninhabitedVariants` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 214f977fee19aeeb4f5ab4df8e0b5d37e611cb48 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 11:08:57 +0100 Subject: Move uninhabited tests into subdirectory. This commit just tries to tidy up a little. --- .../auxiliary/uninhabited.rs | 25 -------- src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs | 38 ------------ .../ui/rfc-2008-non-exhaustive/uninhabited.stderr | 47 -------------- .../uninhabited/auxiliary/uninhabited.rs | 25 ++++++++ .../uninhabited/coercions.rs | 38 ++++++++++++ .../uninhabited/coercions.stderr | 47 ++++++++++++++ .../uninhabited/coercions_same_crate.rs | 46 ++++++++++++++ .../uninhabited/coercions_same_crate.stderr | 47 ++++++++++++++ .../rfc-2008-non-exhaustive/uninhabited/match.rs | 19 ++++++ .../uninhabited/match.stderr | 11 ++++ .../uninhabited/match_same_crate.rs | 18 ++++++ .../uninhabited/match_with_exhaustive_patterns.rs | 22 +++++++ .../match_with_exhaustive_patterns.stderr | 11 ++++ .../match_with_exhaustive_patterns_same_crate.rs | 21 +++++++ .../uninhabited/patterns.rs | 59 ++++++++++++++++++ .../uninhabited/patterns_same_crate.rs | 71 ++++++++++++++++++++++ .../uninhabited/patterns_same_crate.stderr | 38 ++++++++++++ .../rfc-2008-non-exhaustive/uninhabited_match.rs | 19 ------ .../uninhabited_match.stderr | 11 ---- .../uninhabited_match_same_crate.rs | 18 ------ .../uninhabited_match_with_exhaustive_patterns.rs | 22 ------- ...inhabited_match_with_exhaustive_patterns.stderr | 11 ---- ...ed_match_with_exhaustive_patterns_same_crate.rs | 21 ------- .../uninhabited_patterns.rs | 59 ------------------ .../uninhabited_patterns_same_crate.rs | 71 ---------------------- .../uninhabited_patterns_same_crate.stderr | 38 ------------ .../uninhabited_same_crate.rs | 46 -------------- .../uninhabited_same_crate.stderr | 47 -------------- 28 files changed, 473 insertions(+), 473 deletions(-) delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs delete mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs deleted file mode 100644 index a4b936e376d..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![crate_type = "rlib"] -#![feature(never_type)] -#![feature(non_exhaustive)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -#[non_exhaustive] -pub struct UninhabitedStruct { - _priv: !, -} - -#[non_exhaustive] -pub struct UninhabitedTupleStruct(!); - -pub enum UninhabitedVariants { - #[non_exhaustive] Tuple(!), - #[non_exhaustive] Struct { x: ! } -} - -pub enum PartiallyInhabitedVariants { - Tuple(u8), - #[non_exhaustive] Struct { x: ! } -} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs deleted file mode 100644 index 80b9dc4c1c3..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs +++ /dev/null @@ -1,38 +0,0 @@ -// aux-build:uninhabited.rs -#![feature(never_type)] - -extern crate uninhabited; - -use uninhabited::{ - UninhabitedEnum, - UninhabitedStruct, - UninhabitedTupleStruct, - UninhabitedVariants, -}; - -// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never -// type can. - -struct A; - -fn can_coerce_never_type_to_anything(x: !) -> A { - x -} - -fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { - x //~ ERROR mismatched types -} - -fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - x //~ ERROR mismatched types -} - -fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { - x //~ ERROR mismatched types -} - -fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { - x //~ ERROR mismatched types -} - -fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr deleted file mode 100644 index 490a6c10117..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/uninhabited.rs:23:5 - | -LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found enum `uninhabited::UninhabitedEnum` - | - = note: expected type `A` - found type `uninhabited::UninhabitedEnum` - -error[E0308]: mismatched types - --> $DIR/uninhabited.rs:27:5 - | -LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found struct `uninhabited::UninhabitedTupleStruct` - | - = note: expected type `A` - found type `uninhabited::UninhabitedTupleStruct` - -error[E0308]: mismatched types - --> $DIR/uninhabited.rs:31:5 - | -LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found struct `uninhabited::UninhabitedStruct` - | - = note: expected type `A` - found type `uninhabited::UninhabitedStruct` - -error[E0308]: mismatched types - --> $DIR/uninhabited.rs:35:5 - | -LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found enum `uninhabited::UninhabitedVariants` - | - = note: expected type `A` - found type `uninhabited::UninhabitedVariants` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs new file mode 100644 index 00000000000..a4b936e376d --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs @@ -0,0 +1,25 @@ +#![crate_type = "rlib"] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs new file mode 100644 index 00000000000..80b9dc4c1c3 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs @@ -0,0 +1,38 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never +// type can. + +struct A; + +fn can_coerce_never_type_to_anything(x: !) -> A { + x +} + +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x //~ ERROR mismatched types +} + +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x //~ ERROR mismatched types +} + +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x //~ ERROR mismatched types +} + +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr new file mode 100644 index 00000000000..d05ee1d39ec --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/coercions.rs:23:5 + | +LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `uninhabited::UninhabitedEnum` + | + = note: expected type `A` + found type `uninhabited::UninhabitedEnum` + +error[E0308]: mismatched types + --> $DIR/coercions.rs:27:5 + | +LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `uninhabited::UninhabitedTupleStruct` + | + = note: expected type `A` + found type `uninhabited::UninhabitedTupleStruct` + +error[E0308]: mismatched types + --> $DIR/coercions.rs:31:5 + | +LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `uninhabited::UninhabitedStruct` + | + = note: expected type `A` + found type `uninhabited::UninhabitedStruct` + +error[E0308]: mismatched types + --> $DIR/coercions.rs:35:5 + | +LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `uninhabited::UninhabitedVariants` + | + = note: expected type `A` + found type `uninhabited::UninhabitedVariants` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs new file mode 100644 index 00000000000..803a542f8aa --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs @@ -0,0 +1,46 @@ +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +struct A; + +// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce +// to any type, as the never type can. + +fn can_coerce_never_type_to_anything(x: !) -> A { + x +} + +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x //~ ERROR mismatched types +} + +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x //~ ERROR mismatched types +} + +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x //~ ERROR mismatched types +} + +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr new file mode 100644 index 00000000000..8f6b709bb1f --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/coercions_same_crate.rs:31:5 + | +LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `UninhabitedEnum` + | + = note: expected type `A` + found type `UninhabitedEnum` + +error[E0308]: mismatched types + --> $DIR/coercions_same_crate.rs:35:5 + | +LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `UninhabitedTupleStruct` + | + = note: expected type `A` + found type `UninhabitedTupleStruct` + +error[E0308]: mismatched types + --> $DIR/coercions_same_crate.rs:39:5 + | +LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `UninhabitedStruct` + | + = note: expected type `A` + found type `UninhabitedStruct` + +error[E0308]: mismatched types + --> $DIR/coercions_same_crate.rs:43:5 + | +LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `UninhabitedVariants` + | + = note: expected type `A` + found type `UninhabitedVariants` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs new file mode 100644 index 00000000000..0166b2e46cb --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs @@ -0,0 +1,19 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr new file mode 100644 index 00000000000..356c6fba32d --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty + --> $DIR/match.rs:16:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs new file mode 100644 index 00000000000..d8b1c3810f3 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -0,0 +1,18 @@ +// compile-pass +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs new file mode 100644 index 00000000000..d82010158cc --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs @@ -0,0 +1,22 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} 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 new file mode 100644 index 00000000000..ec2e9d0995b --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty + --> $DIR/match_with_exhaustive_patterns.rs:19:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 00000000000..da814a70a75 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,21 @@ +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs new file mode 100644 index 00000000000..97061310d19 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs @@ -0,0 +1,59 @@ +// aux-build:uninhabited.rs +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] + +extern crate uninhabited; + +use uninhabited::{ + PartiallyInhabitedVariants, + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are not considered uninhabited from extern crates. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // This line would normally error. + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // This line would normally error. + None => (), + } + + // This line would normally error. + while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { + } + + while let Some(_x) = uninhabited_struct() { // This line would normally error. + } + + while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs new file mode 100644 index 00000000000..302a35cab5f --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs @@ -0,0 +1,71 @@ +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are still considered uninhabited. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + //~^ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr new file mode 100644 index 00000000000..72f37d9a60b --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr @@ -0,0 +1,38 @@ +error: unreachable pattern + --> $DIR/patterns_same_crate.rs:53:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/patterns_same_crate.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/patterns_same_crate.rs:58:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/patterns_same_crate.rs:62:15 + | +LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/patterns_same_crate.rs:66:15 + | +LL | while let Some(_x) = uninhabited_struct() { + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/patterns_same_crate.rs:69:15 + | +LL | while let Some(_x) = uninhabited_tuple_struct() { + | ^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs deleted file mode 100644 index 0166b2e46cb..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs +++ /dev/null @@ -1,19 +0,0 @@ -// aux-build:uninhabited.rs -#![feature(never_type)] - -extern crate uninhabited; - -use uninhabited::{ - UninhabitedEnum, -}; - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate -// will not compile. - -fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr deleted file mode 100644 index 3000e1b0930..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/uninhabited_match.rs:16:11 - | -LL | match x {} - | ^ - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs deleted file mode 100644 index d8b1c3810f3..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs +++ /dev/null @@ -1,18 +0,0 @@ -// compile-pass -#![feature(never_type)] -#![feature(non_exhaustive)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate -// will compile. - -fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { - match x {} -} - -fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs deleted file mode 100644 index d82010158cc..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs +++ /dev/null @@ -1,22 +0,0 @@ -// aux-build:uninhabited.rs -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] - -extern crate uninhabited; - -use uninhabited::{ - UninhabitedEnum, -}; - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate -// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can -// change the branch used in the compiler to determine this. - -fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { - match x {} //~ ERROR non-exhaustive patterns -} - -fn main() {} 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 deleted file mode 100644 index 73d9e689b55..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/uninhabited_match_with_exhaustive_patterns.rs:19:11 - | -LL | match x {} - | ^ - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs deleted file mode 100644 index da814a70a75..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs +++ /dev/null @@ -1,21 +0,0 @@ -// compile-pass -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] -#![feature(non_exhaustive)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -struct A; - -// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate -// will compile. In particular, this enables the `exhaustive_patterns` feature as this can -// change the branch used in the compiler to determine this. - -fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { - match x {} -} - -fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs deleted file mode 100644 index 97061310d19..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs +++ /dev/null @@ -1,59 +0,0 @@ -// aux-build:uninhabited.rs -// compile-pass -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] - -extern crate uninhabited; - -use uninhabited::{ - PartiallyInhabitedVariants, - UninhabitedEnum, - UninhabitedStruct, - UninhabitedTupleStruct, - UninhabitedVariants, -}; - -fn uninhabited_enum() -> Option { - None -} - -fn uninhabited_variant() -> Option { - None -} - -fn partially_inhabited_variant() -> PartiallyInhabitedVariants { - PartiallyInhabitedVariants::Tuple(3) -} - -fn uninhabited_struct() -> Option { - None -} - -fn uninhabited_tuple_struct() -> Option { - None -} - -// This test checks that non-exhaustive types that would normally be considered uninhabited within -// the defining crate are not considered uninhabited from extern crates. - -fn main() { - match uninhabited_enum() { - Some(_x) => (), // This line would normally error. - None => (), - } - - match uninhabited_variant() { - Some(_x) => (), // This line would normally error. - None => (), - } - - // This line would normally error. - while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { - } - - while let Some(_x) = uninhabited_struct() { // This line would normally error. - } - - while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. - } -} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs deleted file mode 100644 index 302a35cab5f..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs +++ /dev/null @@ -1,71 +0,0 @@ -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] -#![feature(never_type)] -#![feature(non_exhaustive)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -#[non_exhaustive] -pub struct UninhabitedTupleStruct(!); - -#[non_exhaustive] -pub struct UninhabitedStruct { - _priv: !, -} - -pub enum UninhabitedVariants { - #[non_exhaustive] Tuple(!), - #[non_exhaustive] Struct { x: ! } -} - -pub enum PartiallyInhabitedVariants { - Tuple(u8), - #[non_exhaustive] Struct { x: ! } -} - -fn uninhabited_enum() -> Option { - None -} - -fn uninhabited_variant() -> Option { - None -} - -fn partially_inhabited_variant() -> PartiallyInhabitedVariants { - PartiallyInhabitedVariants::Tuple(3) -} - -fn uninhabited_struct() -> Option { - None -} - -fn uninhabited_tuple_struct() -> Option { - None -} - -// This test checks that non-exhaustive types that would normally be considered uninhabited within -// the defining crate are still considered uninhabited. - -fn main() { - match uninhabited_enum() { - Some(_x) => (), //~ ERROR unreachable pattern - None => (), - } - - match uninhabited_variant() { - Some(_x) => (), //~ ERROR unreachable pattern - None => (), - } - - while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { - //~^ ERROR unreachable pattern - } - - while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern - } - - while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern - } -} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr deleted file mode 100644 index 8e995632b2f..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:53:9 - | -LL | Some(_x) => (), - | ^^^^^^^^ - | -note: lint level defined here - --> $DIR/uninhabited_patterns_same_crate.rs:1:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:58:9 - | -LL | Some(_x) => (), - | ^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:62:15 - | -LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:66:15 - | -LL | while let Some(_x) = uninhabited_struct() { - | ^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:69:15 - | -LL | while let Some(_x) = uninhabited_tuple_struct() { - | ^^^^^^^^ - -error: aborting due to 5 previous errors - diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs deleted file mode 100644 index 803a542f8aa..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![feature(never_type)] -#![feature(non_exhaustive)] - -#[non_exhaustive] -pub enum UninhabitedEnum { -} - -#[non_exhaustive] -pub struct UninhabitedTupleStruct(!); - -#[non_exhaustive] -pub struct UninhabitedStruct { - _priv: !, -} - -pub enum UninhabitedVariants { - #[non_exhaustive] Tuple(!), - #[non_exhaustive] Struct { x: ! } -} - -struct A; - -// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce -// to any type, as the never type can. - -fn can_coerce_never_type_to_anything(x: !) -> A { - x -} - -fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { - x //~ ERROR mismatched types -} - -fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - x //~ ERROR mismatched types -} - -fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { - x //~ ERROR mismatched types -} - -fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { - x //~ ERROR mismatched types -} - -fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr deleted file mode 100644 index ea79e7105d5..00000000000 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:31:5 - | -LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found enum `UninhabitedEnum` - | - = note: expected type `A` - found type `UninhabitedEnum` - -error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:35:5 - | -LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found struct `UninhabitedTupleStruct` - | - = note: expected type `A` - found type `UninhabitedTupleStruct` - -error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:39:5 - | -LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found struct `UninhabitedStruct` - | - = note: expected type `A` - found type `UninhabitedStruct` - -error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:43:5 - | -LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { - | - expected `A` because of return type -LL | x - | ^ expected struct `A`, found enum `UninhabitedVariants` - | - = note: expected type `A` - found type `UninhabitedVariants` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 1f0fb0391caf232dacabdf73fbbb84f2452b25c1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 12:07:04 +0100 Subject: Add a bunch more tests. --- .../uninhabited/auxiliary/uninhabited.rs | 8 +++ .../uninhabited/indirect_match.rs | 36 +++++++++++++ .../uninhabited/indirect_match.stderr | 35 +++++++++++++ .../uninhabited/indirect_match_same_crate.rs | 52 +++++++++++++++++++ .../uninhabited/indirect_match_same_crate.stderr | 59 ++++++++++++++++++++++ .../indirect_match_with_exhaustive_patterns.rs | 40 +++++++++++++++ .../indirect_match_with_exhaustive_patterns.stderr | 35 +++++++++++++ ...ct_match_with_exhaustive_patterns_same_crate.rs | 58 +++++++++++++++++++++ .../rfc-2008-non-exhaustive/uninhabited/match.rs | 15 ++++++ .../uninhabited/match.stderr | 28 +++++++++- .../uninhabited/match_same_crate.rs | 26 +++++++++- .../uninhabited/match_same_crate.stderr | 49 ++++++++++++++++++ .../uninhabited/match_with_exhaustive_patterns.rs | 15 ++++++ .../match_with_exhaustive_patterns.stderr | 28 +++++++++- .../match_with_exhaustive_patterns_same_crate.rs | 27 ++++++++++ 15 files changed, 506 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs index a4b936e376d..8cb9a8cf1f6 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs @@ -23,3 +23,11 @@ pub enum PartiallyInhabitedVariants { Tuple(u8), #[non_exhaustive] Struct { x: ! } } + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs new file mode 100644 index 00000000000..98a7fdbc504 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs @@ -0,0 +1,36 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + IndirectUninhabitedEnum, + IndirectUninhabitedStruct, + IndirectUninhabitedTupleStruct, + IndirectUninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from an extern crate will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr new file mode 100644 index 00000000000..af82022e1da --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr @@ -0,0 +1,35 @@ +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `uninhabited::IndirectUninhabitedEnum` is not handled + --> $DIR/indirect_match.rs:19:11 + | +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: pattern `IndirectUninhabitedStruct` of type `uninhabited::IndirectUninhabitedStruct` is not handled + --> $DIR/indirect_match.rs:23:11 + | +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: pattern `IndirectUninhabitedTupleStruct` of type `uninhabited::IndirectUninhabitedTupleStruct` is not handled + --> $DIR/indirect_match.rs:27:11 + | +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: pattern `IndirectUninhabitedVariants` of type `uninhabited::IndirectUninhabitedVariants` is not handled + --> $DIR/indirect_match.rs:33:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs new file mode 100644 index 00000000000..3c8d495e12c --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs @@ -0,0 +1,52 @@ +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from the defining crate will not compile without `#![feature(exhaustive_patterns)]`. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr new file mode 100644 index 00000000000..27b120792d6 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr @@ -0,0 +1,59 @@ +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `IndirectUninhabitedEnum` is not handled + --> $DIR/indirect_match_same_crate.rs:35:11 + | +LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum); + | ---------------------------------------------------- + | | | + | | variant not covered + | `IndirectUninhabitedEnum` defined here +... +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: pattern `IndirectUninhabitedStruct` of type `IndirectUninhabitedStruct` is not handled + --> $DIR/indirect_match_same_crate.rs:39:11 + | +LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct); + | -------------------------------------------------------- + | | | + | | variant not covered + | `IndirectUninhabitedStruct` defined here +... +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: pattern `IndirectUninhabitedTupleStruct` of type `IndirectUninhabitedTupleStruct` is not handled + --> $DIR/indirect_match_same_crate.rs:43:11 + | +LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + | ------------------------------------------------------------------ + | | | + | | variant not covered + | `IndirectUninhabitedTupleStruct` defined here +... +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: pattern `IndirectUninhabitedVariants` of type `IndirectUninhabitedVariants` is not handled + --> $DIR/indirect_match_same_crate.rs:49:11 + | +LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants); + | ------------------------------------------------------------ + | | | + | | variant not covered + | `IndirectUninhabitedVariants` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs new file mode 100644 index 00000000000..be86519ecb1 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs @@ -0,0 +1,40 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + IndirectUninhabitedEnum, + IndirectUninhabitedStruct, + IndirectUninhabitedTupleStruct, + IndirectUninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from an extern crate will not compile. In particular, this enables the +// `exhaustive_patterns` feature as this can change the branch used in the compiler to determine +// this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} 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 new file mode 100644 index 00000000000..17a8d010072 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr @@ -0,0 +1,35 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedEnum` is non-empty + --> $DIR/indirect_match_with_exhaustive_patterns.rs:23:11 + | +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 + --> $DIR/indirect_match_with_exhaustive_patterns.rs:27:11 + | +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 + --> $DIR/indirect_match_with_exhaustive_patterns.rs:31:11 + | +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 + --> $DIR/indirect_match_with_exhaustive_patterns.rs:37:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 00000000000..5dbd38e07df --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,58 @@ +// compile-pass +// skip-codegen +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. +// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs index 0166b2e46cb..e54098d4d48 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs @@ -5,6 +5,9 @@ extern crate uninhabited; use uninhabited::{ UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, }; struct A; @@ -16,4 +19,16 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} //~ ERROR non-exhaustive patterns } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr index 356c6fba32d..de39688f45a 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr @@ -1,11 +1,35 @@ error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/match.rs:16:11 + --> $DIR/match.rs:19:11 | LL | match x {} | ^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: aborting due to previous error +error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `uninhabited::UninhabitedStruct` is not handled + --> $DIR/match.rs:23:11 + | +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: pattern `UninhabitedTupleStruct` of type `uninhabited::UninhabitedTupleStruct` is not handled + --> $DIR/match.rs:27:11 + | +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: multiple patterns of type `uninhabited::UninhabitedVariants` are not handled + --> $DIR/match.rs:31:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs index d8b1c3810f3..6405dd3bd65 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -1,4 +1,3 @@ -// compile-pass #![feature(never_type)] #![feature(non_exhaustive)] @@ -6,6 +5,19 @@ pub enum UninhabitedEnum { } +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + struct A; // This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate @@ -15,4 +27,16 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr new file mode 100644 index 00000000000..410285a39a9 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr @@ -0,0 +1,49 @@ +error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `UninhabitedStruct` is not handled + --> $DIR/match_same_crate.rs:31:11 + | +LL | pub struct UninhabitedStruct { + | - ----------------- variant not covered + | _| + | | +LL | | _priv: !, +LL | | } + | |_- `UninhabitedStruct` defined here +... +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: pattern `UninhabitedTupleStruct` of type `UninhabitedTupleStruct` is not handled + --> $DIR/match_same_crate.rs:35:11 + | +LL | pub struct UninhabitedTupleStruct(!); + | ------------------------------------- + | | | + | | variant not covered + | `UninhabitedTupleStruct` defined here +... +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: multiple patterns of type `UninhabitedVariants` are not handled + --> $DIR/match_same_crate.rs:39:11 + | +LL | / pub enum UninhabitedVariants { +LL | | #[non_exhaustive] Tuple(!), + | | ----- variant not covered +LL | | #[non_exhaustive] Struct { x: ! } + | | ------ variant not covered +LL | | } + | |_- `UninhabitedVariants` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs index d82010158cc..900dfff652e 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs @@ -7,6 +7,9 @@ extern crate uninhabited; use uninhabited::{ UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, }; struct A; @@ -19,4 +22,16 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} //~ ERROR non-exhaustive patterns } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + fn main() {} 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 ec2e9d0995b..48a888bc50b 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 @@ -1,11 +1,35 @@ error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/match_with_exhaustive_patterns.rs:19:11 + --> $DIR/match_with_exhaustive_patterns.rs:22:11 | LL | match x {} | ^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: aborting due to previous error +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedStruct` is non-empty + --> $DIR/match_with_exhaustive_patterns.rs:26:11 + | +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 + --> $DIR/match_with_exhaustive_patterns.rs:30:11 + | +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 + --> $DIR/match_with_exhaustive_patterns.rs:34:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs index da814a70a75..74922d4bcb5 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs @@ -1,4 +1,5 @@ // compile-pass +// skip-codegen #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] #![feature(never_type)] @@ -8,14 +9,40 @@ pub enum UninhabitedEnum { } +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + struct A; // This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate // will compile. In particular, this enables the `exhaustive_patterns` feature as this can // change the branch used in the compiler to determine this. +// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} +} + fn main() {} -- cgit 1.4.1-3-g733a5