Skip to content

Commit 0db087e

Browse files
committed
Add uninhabitedness tests w/ #[non_exhaustive].
This commit adds tests checking that uninhabited non-exhaustive types are considered inhabited when used in another crate.
1 parent 0ac53da commit 0db087e

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![crate_type = "rlib"]
2+
#![feature(never_type)]
3+
#![feature(non_exhaustive)]
4+
5+
#[non_exhaustive]
6+
pub enum UninhabitedEnum {
7+
}
8+
9+
#[non_exhaustive]
10+
pub struct UninhabitedStruct {
11+
_priv: !,
12+
}
13+
14+
#[non_exhaustive]
15+
pub struct UninhabitedTupleStruct(!);
16+
17+
pub enum UninhabitedVariants {
18+
#[non_exhaustive] Tuple(!),
19+
#[non_exhaustive] Struct { x: ! }
20+
}
21+
22+
pub enum PartiallyInhabitedVariants {
23+
Tuple(u8),
24+
#[non_exhaustive] Struct { x: ! }
25+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// aux-build:uninhabited.rs
2+
// compile-pass
3+
#![deny(unreachable_patterns)]
4+
#![feature(exhaustive_patterns)]
5+
6+
extern crate uninhabited;
7+
8+
use uninhabited::{
9+
PartiallyInhabitedVariants,
10+
UninhabitedEnum,
11+
UninhabitedStruct,
12+
UninhabitedTupleStruct,
13+
UninhabitedVariants,
14+
};
15+
16+
fn uninhabited_enum() -> Option<UninhabitedEnum> {
17+
None
18+
}
19+
20+
fn uninhabited_variant() -> Option<UninhabitedVariants> {
21+
None
22+
}
23+
24+
fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
25+
PartiallyInhabitedVariants::Tuple(3)
26+
}
27+
28+
fn uninhabited_struct() -> Option<UninhabitedStruct> {
29+
None
30+
}
31+
32+
fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
33+
None
34+
}
35+
36+
// This test checks that non-exhaustive types that would normally be considered uninhabited within
37+
// the defining crate are not considered uninhabited from extern crates.
38+
39+
fn main() {
40+
match uninhabited_enum() {
41+
Some(_x) => (), // This line would normally error.
42+
None => (),
43+
}
44+
45+
match uninhabited_variant() {
46+
Some(_x) => (), // This line would normally error.
47+
None => (),
48+
}
49+
50+
// This line would normally error.
51+
while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {
52+
}
53+
54+
while let Some(_x) = uninhabited_struct() { // This line would normally error.
55+
}
56+
57+
while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error.
58+
}
59+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![deny(unreachable_patterns)]
2+
#![feature(exhaustive_patterns)]
3+
#![feature(never_type)]
4+
#![feature(non_exhaustive)]
5+
6+
#[non_exhaustive]
7+
pub enum UninhabitedEnum {
8+
}
9+
10+
#[non_exhaustive]
11+
pub struct UninhabitedTupleStruct(!);
12+
13+
#[non_exhaustive]
14+
pub struct UninhabitedStruct {
15+
_priv: !,
16+
}
17+
18+
pub enum UninhabitedVariants {
19+
#[non_exhaustive] Tuple(!),
20+
#[non_exhaustive] Struct { x: ! }
21+
}
22+
23+
pub enum PartiallyInhabitedVariants {
24+
Tuple(u8),
25+
#[non_exhaustive] Struct { x: ! }
26+
}
27+
28+
fn uninhabited_enum() -> Option<UninhabitedEnum> {
29+
None
30+
}
31+
32+
fn uninhabited_variant() -> Option<UninhabitedVariants> {
33+
None
34+
}
35+
36+
fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
37+
PartiallyInhabitedVariants::Tuple(3)
38+
}
39+
40+
fn uninhabited_struct() -> Option<UninhabitedStruct> {
41+
None
42+
}
43+
44+
fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
45+
None
46+
}
47+
48+
// This test checks that non-exhaustive types that would normally be considered uninhabited within
49+
// the defining crate are still considered uninhabited.
50+
51+
fn main() {
52+
match uninhabited_enum() {
53+
Some(_x) => (), //~ ERROR unreachable pattern
54+
None => (),
55+
}
56+
57+
match uninhabited_variant() {
58+
Some(_x) => (), //~ ERROR unreachable pattern
59+
None => (),
60+
}
61+
62+
while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
63+
//~^ ERROR unreachable pattern
64+
}
65+
66+
while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern
67+
}
68+
69+
while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern
70+
}
71+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
error: unreachable pattern
2+
--> $DIR/uninhabited_same_crate.rs:53:9
3+
|
4+
LL | Some(_x) => (),
5+
| ^^^^^^^^
6+
|
7+
note: lint level defined here
8+
--> $DIR/uninhabited_same_crate.rs:1:9
9+
|
10+
LL | #![deny(unreachable_patterns)]
11+
| ^^^^^^^^^^^^^^^^^^^^
12+
13+
error: unreachable pattern
14+
--> $DIR/uninhabited_same_crate.rs:58:9
15+
|
16+
LL | Some(_x) => (),
17+
| ^^^^^^^^
18+
19+
error: unreachable pattern
20+
--> $DIR/uninhabited_same_crate.rs:62:15
21+
|
22+
LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error: unreachable pattern
26+
--> $DIR/uninhabited_same_crate.rs:66:15
27+
|
28+
LL | while let Some(_x) = uninhabited_struct() {
29+
| ^^^^^^^^
30+
31+
error: unreachable pattern
32+
--> $DIR/uninhabited_same_crate.rs:69:15
33+
|
34+
LL | while let Some(_x) = uninhabited_tuple_struct() {
35+
| ^^^^^^^^
36+
37+
error: aborting due to 5 previous errors
38+

0 commit comments

Comments
 (0)