From 0db087e6840cc865bcf8be09ff940f2ac13341ac Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 01:15:26 +0100 Subject: [PATCH] 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 +++++++ .../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 +