Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6f6a6bc

Browse files
committedSep 2, 2024·
Non-exhaustive structs may be empty
1 parent bd53aa3 commit 6f6a6bc

16 files changed

+135
-207
lines changed
 

‎compiler/rustc_middle/src/ty/inhabitedness/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ impl<'tcx> VariantDef {
8181
adt: ty::AdtDef<'_>,
8282
) -> InhabitedPredicate<'tcx> {
8383
debug_assert!(!adt.is_union());
84-
if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
85-
// Non-exhaustive variants from other crates are always considered inhabited.
86-
return InhabitedPredicate::True;
87-
}
8884
InhabitedPredicate::all(
8985
tcx,
9086
self.fields.iter().map(|field| {

‎compiler/rustc_pattern_analysis/src/rustc.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
229229
} else {
230230
let variant =
231231
&adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt));
232-
233-
// In the cases of either a `#[non_exhaustive]` field list or a non-public
234-
// field, we skip uninhabited fields in order not to reveal the
235-
// uninhabitedness of the whole variant.
236-
let is_non_exhaustive =
237-
variant.is_field_list_non_exhaustive() && !adt.did().is_local();
238232
let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
239233
let is_visible =
240234
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
241235
let is_uninhabited = cx.is_uninhabited(*ty);
242-
let skip = is_uninhabited && (!is_visible || is_non_exhaustive);
236+
let skip = is_uninhabited && !is_visible;
243237
(ty, PrivateUninhabitedField(skip))
244238
});
245239
cx.dropless_arena.alloc_from_iter(tys)

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ pub enum UninhabitedEnum {
77

88
#[non_exhaustive]
99
pub struct UninhabitedStruct {
10-
_priv: !,
10+
pub never: !,
11+
_priv: (),
1112
}
1213

1314
#[non_exhaustive]
14-
pub struct UninhabitedTupleStruct(!);
15+
pub struct PrivatelyUninhabitedStruct {
16+
never: !,
17+
}
18+
19+
#[non_exhaustive]
20+
pub struct UninhabitedTupleStruct(pub !);
1521

1622
pub enum UninhabitedVariants {
1723
#[non_exhaustive] Tuple(!),

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {}
55
| ^
66
|
77
note: `IndirectUninhabitedEnum` defined here
8-
--> $DIR/auxiliary/uninhabited.rs:26:1
8+
--> $DIR/auxiliary/uninhabited.rs:32:1
99
|
1010
LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL | match x {}
2424
| ^
2525
|
2626
note: `IndirectUninhabitedStruct` defined here
27-
--> $DIR/auxiliary/uninhabited.rs:28:1
27+
--> $DIR/auxiliary/uninhabited.rs:34:1
2828
|
2929
LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ LL | match x {}
4343
| ^
4444
|
4545
note: `IndirectUninhabitedTupleStruct` defined here
46-
--> $DIR/auxiliary/uninhabited.rs:30:1
46+
--> $DIR/auxiliary/uninhabited.rs:36:1
4747
|
4848
LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
4949
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL | match x {}
6262
| ^
6363
|
6464
note: `IndirectUninhabitedVariants` defined here
65-
--> $DIR/auxiliary/uninhabited.rs:32:1
65+
--> $DIR/auxiliary/uninhabited.rs:38:1
6666
|
6767
LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
6868
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {}
55
| ^
66
|
77
note: `IndirectUninhabitedEnum` defined here
8-
--> $DIR/auxiliary/uninhabited.rs:26:1
8+
--> $DIR/auxiliary/uninhabited.rs:32:1
99
|
1010
LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL | match x {}
2424
| ^
2525
|
2626
note: `IndirectUninhabitedStruct` defined here
27-
--> $DIR/auxiliary/uninhabited.rs:28:1
27+
--> $DIR/auxiliary/uninhabited.rs:34:1
2828
|
2929
LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ LL | match x {}
4343
| ^
4444
|
4545
note: `IndirectUninhabitedTupleStruct` defined here
46-
--> $DIR/auxiliary/uninhabited.rs:30:1
46+
--> $DIR/auxiliary/uninhabited.rs:36:1
4747
|
4848
LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
4949
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL | match x {}
6262
| ^
6363
|
6464
note: `IndirectUninhabitedVariants` defined here
65-
--> $DIR/auxiliary/uninhabited.rs:32:1
65+
--> $DIR/auxiliary/uninhabited.rs:38:1
6666
|
6767
LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
6868
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use uninhabited::PartiallyInhabitedVariants;
1111

1212
pub fn foo(x: PartiallyInhabitedVariants) {
1313
match x {
14-
PartiallyInhabitedVariants::Struct { .. } => {},
15-
PartiallyInhabitedVariants::Struct { .. } => {},
14+
PartiallyInhabitedVariants::Struct { .. } => {}
1615
//~^ ERROR unreachable pattern
17-
_ => {},
16+
PartiallyInhabitedVariants::Struct { .. } => {}
17+
//~^ ERROR unreachable pattern
18+
_ => {}
1819
}
1920
}
2021

21-
fn main() { }
22+
fn main() {}
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
error: unreachable pattern
2-
--> $DIR/issue-65157-repeated-match-arm.rs:15:9
2+
--> $DIR/issue-65157-repeated-match-arm.rs:14:9
33
|
4-
LL | PartiallyInhabitedVariants::Struct { .. } => {},
5-
| ----------------------------------------- matches all the relevant values
6-
LL | PartiallyInhabitedVariants::Struct { .. } => {},
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
4+
LL | PartiallyInhabitedVariants::Struct { .. } => {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
86
|
7+
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
98
note: the lint level is defined here
109
--> $DIR/issue-65157-repeated-match-arm.rs:2:9
1110
|
1211
LL | #![deny(unreachable_patterns)]
1312
| ^^^^^^^^^^^^^^^^^^^^
1413

15-
error: aborting due to 1 previous error
14+
error: unreachable pattern
15+
--> $DIR/issue-65157-repeated-match-arm.rs:16:9
16+
|
17+
LL | PartiallyInhabitedVariants::Struct { .. } => {}
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
19+
|
20+
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
21+
22+
error: aborting due to 2 previous errors
1623

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@
33

44
extern crate uninhabited;
55

6-
use uninhabited::{
7-
UninhabitedEnum,
8-
UninhabitedStruct,
9-
UninhabitedTupleStruct,
10-
UninhabitedVariants,
11-
};
6+
use uninhabited::*;
127

138
struct A;
149

@@ -19,16 +14,20 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
1914
match x {} //~ ERROR non-exhaustive patterns
2015
}
2116

22-
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
23-
match x {} //~ ERROR non-exhaustive patterns
17+
fn empty_match_on_empty_struct(x: UninhabitedStruct) -> A {
18+
match x {}
2419
}
2520

26-
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
21+
fn cannot_empty_match_on_privately_empty_struct(x: PrivatelyUninhabitedStruct) -> A {
2722
match x {} //~ ERROR non-exhaustive patterns
2823
}
2924

30-
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
31-
match x {} //~ ERROR non-exhaustive patterns
25+
fn empty_match_on_empty_tuple_struct(x: UninhabitedTupleStruct) -> A {
26+
match x {}
27+
}
28+
29+
fn empty_match_on_enum_with_empty_variants_struct(x: UninhabitedVariants) -> A {
30+
match x {}
3231
}
3332

3433
fn main() {}
Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,41 @@
1-
error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
2-
--> $DIR/match.rs:19:11
1+
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty
2+
--> $DIR/match.rs:14:11
33
|
44
LL | match x {}
55
| ^
66
|
7-
note: `UninhabitedEnum` defined here
7+
note: `uninhabited::UninhabitedEnum` defined here
88
--> $DIR/auxiliary/uninhabited.rs:5:1
99
|
1010
LL | pub enum UninhabitedEnum {
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^
12-
= note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
12+
= note: the matched value is of type `uninhabited::UninhabitedEnum`, which is marked as non-exhaustive
1313
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
1414
|
1515
LL ~ match x {
1616
LL + _ => todo!(),
1717
LL ~ }
1818
|
1919

20-
error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
21-
--> $DIR/match.rs:23:11
20+
error[E0004]: non-exhaustive patterns: type `uninhabited::PrivatelyUninhabitedStruct` is non-empty
21+
--> $DIR/match.rs:22:11
2222
|
2323
LL | match x {}
2424
| ^
2525
|
26-
note: `UninhabitedStruct` defined here
27-
--> $DIR/auxiliary/uninhabited.rs:9:1
26+
note: `uninhabited::PrivatelyUninhabitedStruct` defined here
27+
--> $DIR/auxiliary/uninhabited.rs:15:1
2828
|
29-
LL | pub struct UninhabitedStruct {
30-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31-
= note: the matched value is of type `UninhabitedStruct`
29+
LL | pub struct PrivatelyUninhabitedStruct {
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
= note: the matched value is of type `uninhabited::PrivatelyUninhabitedStruct`
3232
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
3333
|
3434
LL ~ match x {
3535
LL + _ => todo!(),
3636
LL ~ }
3737
|
3838

39-
error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
40-
--> $DIR/match.rs:27:11
41-
|
42-
LL | match x {}
43-
| ^
44-
|
45-
note: `UninhabitedTupleStruct` defined here
46-
--> $DIR/auxiliary/uninhabited.rs:14:1
47-
|
48-
LL | pub struct UninhabitedTupleStruct(!);
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50-
= note: the matched value is of type `UninhabitedTupleStruct`
51-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
52-
|
53-
LL ~ match x {
54-
LL + _ => todo!(),
55-
LL ~ }
56-
|
57-
58-
error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
59-
--> $DIR/match.rs:31:11
60-
|
61-
LL | match x {}
62-
| ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
63-
|
64-
note: `UninhabitedVariants` defined here
65-
--> $DIR/auxiliary/uninhabited.rs:16:1
66-
|
67-
LL | pub enum UninhabitedVariants {
68-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
69-
LL | #[non_exhaustive] Tuple(!),
70-
| ----- not covered
71-
LL | #[non_exhaustive] Struct { x: ! }
72-
| ------ not covered
73-
= note: the matched value is of type `UninhabitedVariants`
74-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
75-
|
76-
LL ~ match x {
77-
LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
78-
LL ~ }
79-
|
80-
81-
error: aborting due to 4 previous errors
39+
error: aborting due to 2 previous errors
8240

8341
For more information about this error, try `rustc --explain E0004`.

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,28 @@
55
extern crate uninhabited;
66

77
use uninhabited::{
8-
UninhabitedEnum,
9-
UninhabitedStruct,
10-
UninhabitedTupleStruct,
11-
UninhabitedVariants,
8+
UninhabitedEnum, UninhabitedStruct, UninhabitedTupleStruct, UninhabitedVariants,
129
};
1310

1411
struct A;
1512

16-
// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate
17-
// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can
18-
// change the branch used in the compiler to determine this.
19-
20-
fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
13+
// This test checks that non-exhaustive enums are never considered uninhabited outside their
14+
// defining crate, and non-exhaustive structs are considered uninhabited the same way as normal
15+
// ones.
16+
fn cannot_empty_match_on_non_exhaustive_empty_enum(x: UninhabitedEnum) -> A {
2117
match x {} //~ ERROR non-exhaustive patterns
2218
}
2319

24-
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
25-
match x {} //~ ERROR non-exhaustive patterns
20+
fn empty_match_on_empty_struct(x: UninhabitedStruct) -> A {
21+
match x {}
2622
}
2723

28-
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
29-
match x {} //~ ERROR non-exhaustive patterns
24+
fn empty_match_on_empty_tuple_struct(x: UninhabitedTupleStruct) -> A {
25+
match x {}
3026
}
3127

32-
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
33-
match x {} //~ ERROR non-exhaustive patterns
28+
fn empty_match_on_enum_with_empty_variants_struct(x: UninhabitedVariants) -> A {
29+
match x {}
3430
}
3531

3632
fn main() {}
Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
2-
--> $DIR/match_with_exhaustive_patterns.rs:21:11
2+
--> $DIR/match_with_exhaustive_patterns.rs:17:11
33
|
44
LL | match x {}
55
| ^
@@ -17,67 +17,6 @@ LL + _ => todo!(),
1717
LL ~ }
1818
|
1919

20-
error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
21-
--> $DIR/match_with_exhaustive_patterns.rs:25:11
22-
|
23-
LL | match x {}
24-
| ^
25-
|
26-
note: `UninhabitedStruct` defined here
27-
--> $DIR/auxiliary/uninhabited.rs:9:1
28-
|
29-
LL | pub struct UninhabitedStruct {
30-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31-
= note: the matched value is of type `UninhabitedStruct`
32-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
33-
|
34-
LL ~ match x {
35-
LL + _ => todo!(),
36-
LL ~ }
37-
|
38-
39-
error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
40-
--> $DIR/match_with_exhaustive_patterns.rs:29:11
41-
|
42-
LL | match x {}
43-
| ^
44-
|
45-
note: `UninhabitedTupleStruct` defined here
46-
--> $DIR/auxiliary/uninhabited.rs:14:1
47-
|
48-
LL | pub struct UninhabitedTupleStruct(!);
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50-
= note: the matched value is of type `UninhabitedTupleStruct`
51-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
52-
|
53-
LL ~ match x {
54-
LL + _ => todo!(),
55-
LL ~ }
56-
|
57-
58-
error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
59-
--> $DIR/match_with_exhaustive_patterns.rs:33:11
60-
|
61-
LL | match x {}
62-
| ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
63-
|
64-
note: `UninhabitedVariants` defined here
65-
--> $DIR/auxiliary/uninhabited.rs:16:1
66-
|
67-
LL | pub enum UninhabitedVariants {
68-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
69-
LL | #[non_exhaustive] Tuple(!),
70-
| ----- not covered
71-
LL | #[non_exhaustive] Struct { x: ! }
72-
| ------ not covered
73-
= note: the matched value is of type `UninhabitedVariants`
74-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
75-
|
76-
LL ~ match x {
77-
LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
78-
LL ~ }
79-
|
80-
81-
error: aborting due to 4 previous errors
20+
error: aborting due to 1 previous error
8221

8322
For more information about this error, try `rustc --explain E0004`.

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//@ check-pass
2-
32
#![deny(unreachable_patterns)]
43
#![feature(never_type)]
54

@@ -9,11 +8,12 @@ pub enum UninhabitedEnum {
98

109
#[non_exhaustive]
1110
pub struct UninhabitedStruct {
12-
_priv: !,
11+
pub never: !,
12+
_priv: (),
1313
}
1414

1515
#[non_exhaustive]
16-
pub struct UninhabitedTupleStruct(!);
16+
pub struct UninhabitedTupleStruct(pub !);
1717

1818
pub enum UninhabitedVariants {
1919
#[non_exhaustive] Tuple(!),
@@ -22,24 +22,21 @@ pub enum UninhabitedVariants {
2222

2323
struct A;
2424

25-
// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
26-
// will compile. In particular, this enables the `exhaustive_patterns` feature as this can
27-
// change the branch used in the compiler to determine this.
28-
// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648.
29-
30-
fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
25+
// This checks that `non_exhaustive` annotations do not affect exhaustiveness checking within the
26+
// defining crate.
27+
fn empty_match_on_empty_enum(x: UninhabitedEnum) -> A {
3128
match x {}
3229
}
3330

34-
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
31+
fn empty_match_on_empty_struct(x: UninhabitedStruct) -> A {
3532
match x {}
3633
}
3734

38-
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
35+
fn empty_match_on_empty_tuple_struct(x: UninhabitedTupleStruct) -> A {
3936
match x {}
4037
}
4138

42-
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
39+
fn empty_match_on_enum_with_empty_variants_struct(x: UninhabitedVariants) -> A {
4340
match x {}
4441
}
4542

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
//@ aux-build:uninhabited.rs
2-
//@ build-pass (FIXME(62277): could be check-pass?)
32
#![deny(unreachable_patterns)]
43

54
extern crate uninhabited;
65

76
use uninhabited::{
8-
PartiallyInhabitedVariants,
9-
UninhabitedEnum,
10-
UninhabitedStruct,
11-
UninhabitedTupleStruct,
7+
PartiallyInhabitedVariants, UninhabitedEnum, UninhabitedStruct, UninhabitedTupleStruct,
128
UninhabitedVariants,
139
};
1410

@@ -32,27 +28,26 @@ fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
3228
None
3329
}
3430

35-
// This test checks that non-exhaustive types that would normally be considered uninhabited within
36-
// the defining crate are not considered uninhabited from extern crates.
37-
31+
// This test checks that non-exhaustive enums are never considered uninhabited outside their
32+
// defining crate, and non-exhaustive structs are considered uninhabited the same way as normal
33+
// ones.
3834
fn main() {
3935
match uninhabited_enum() {
40-
Some(_x) => (), // This line would normally error.
36+
Some(_x) => (), // This would error without `non_exhaustive`
4137
None => (),
4238
}
4339

4440
match uninhabited_variant() {
45-
Some(_x) => (), // This line would normally error.
41+
Some(_x) => (), //~ ERROR unreachable
4642
None => (),
4743
}
4844

4945
// This line would normally error.
50-
while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {
51-
}
46+
while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {} //~ ERROR unreachable
5247

53-
while let Some(_x) = uninhabited_struct() { // This line would normally error.
48+
while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable
5449
}
5550

56-
while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error.
51+
while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable
5752
}
5853
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error: unreachable pattern
2+
--> $DIR/patterns.rs:41:9
3+
|
4+
LL | Some(_x) => (),
5+
| ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
6+
|
7+
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
8+
note: the lint level is defined here
9+
--> $DIR/patterns.rs:2:9
10+
|
11+
LL | #![deny(unreachable_patterns)]
12+
| ^^^^^^^^^^^^^^^^^^^^
13+
14+
error: unreachable pattern
15+
--> $DIR/patterns.rs:46:15
16+
|
17+
LL | while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {}
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
19+
|
20+
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
21+
22+
error: unreachable pattern
23+
--> $DIR/patterns.rs:48:15
24+
|
25+
LL | while let Some(_x) = uninhabited_struct() {
26+
| ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
27+
|
28+
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
29+
30+
error: unreachable pattern
31+
--> $DIR/patterns.rs:51:15
32+
|
33+
LL | while let Some(_x) = uninhabited_tuple_struct() {
34+
| ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited
35+
|
36+
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
37+
38+
error: aborting due to 4 previous errors
39+

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ pub enum UninhabitedEnum {
66
}
77

88
#[non_exhaustive]
9-
pub struct UninhabitedTupleStruct(!);
9+
pub struct UninhabitedTupleStruct(pub !);
1010

1111
#[non_exhaustive]
1212
pub struct UninhabitedStruct {
13-
_priv: !,
13+
pub never: !,
14+
_priv: (),
1415
}
1516

1617
pub enum UninhabitedVariants {

‎tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unreachable pattern
2-
--> $DIR/patterns_same_crate.rs:51:9
2+
--> $DIR/patterns_same_crate.rs:52:9
33
|
44
LL | Some(_x) => (),
55
| ^^^^^^^^ matches no values because `UninhabitedEnum` is uninhabited
@@ -12,31 +12,31 @@ LL | #![deny(unreachable_patterns)]
1212
| ^^^^^^^^^^^^^^^^^^^^
1313

1414
error: unreachable pattern
15-
--> $DIR/patterns_same_crate.rs:56:9
15+
--> $DIR/patterns_same_crate.rs:57:9
1616
|
1717
LL | Some(_x) => (),
1818
| ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
1919
|
2020
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
2121

2222
error: unreachable pattern
23-
--> $DIR/patterns_same_crate.rs:60:15
23+
--> $DIR/patterns_same_crate.rs:61:15
2424
|
2525
LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
2727
|
2828
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
2929

3030
error: unreachable pattern
31-
--> $DIR/patterns_same_crate.rs:64:15
31+
--> $DIR/patterns_same_crate.rs:65:15
3232
|
3333
LL | while let Some(_x) = uninhabited_struct() {
3434
| ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
3535
|
3636
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
3737

3838
error: unreachable pattern
39-
--> $DIR/patterns_same_crate.rs:67:15
39+
--> $DIR/patterns_same_crate.rs:68:15
4040
|
4141
LL | while let Some(_x) = uninhabited_tuple_struct() {
4242
| ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited

0 commit comments

Comments
 (0)
Please sign in to comment.