Skip to content

Commit 949e552

Browse files
authored
Rollup merge of rust-lang#120775 - Nadrieril:more-min_exh_pats, r=compiler-errors
Make `min_exhaustive_patterns` match `exhaustive_patterns` better Split off from rust-lang#120742. There remained two edge cases where `min_exhaustive_patterns` wasn't behaving like `exhaustive_patterns`. This fixes them, and tests the feature in a bunch more cases. I essentially went through all uses of `exhaustive_patterns` to see which ones would be interesting to compare between the two features. r? `@compiler-errors`
2 parents abef17d + 4733b1b commit 949e552

18 files changed

+192
-25
lines changed

compiler/rustc_mir_build/src/build/matches/simplify.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
270270
PatKind::Variant { adt_def, args, variant_index, ref subpatterns } => {
271271
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
272272
i == variant_index || {
273-
self.tcx.features().exhaustive_patterns
273+
(self.tcx.features().exhaustive_patterns
274+
|| self.tcx.features().min_exhaustive_patterns)
274275
&& !v
275276
.inhabited_predicate(self.tcx, adt_def)
276277
.instantiate(self.tcx, args)

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
665665

666666
// Emit an extra note if the first uncovered witness would be uninhabited
667667
// if we disregard visibility.
668-
let witness_1_is_privately_uninhabited = if self.tcx.features().exhaustive_patterns
668+
let witness_1_is_privately_uninhabited = if (self.tcx.features().exhaustive_patterns
669+
|| self.tcx.features().min_exhaustive_patterns)
669670
&& let Some(witness_1) = witnesses.get(0)
670671
&& let ty::Adt(adt, args) = witness_1.ty().kind()
671672
&& adt.is_enum()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/multivariant.rs:7:46
3+
|
4+
LL | #![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #119612 <https://github.com/rust-lang/rust/issues/119612> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// Test precise capture of a multi-variant enum (when remaining variants are
22
// visibly uninhabited).
3+
// revisions: min_exhaustive_patterns exhaustive_patterns
34
// edition:2021
45
// run-pass
5-
#![feature(exhaustive_patterns)]
6+
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
7+
#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
8+
//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
69
#![feature(never_type)]
710

811
pub fn main() {

tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr renamed to tests/ui/pattern/usefulness/always-inhabited-union-ref.exhaustive_patterns.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
2-
--> $DIR/always-inhabited-union-ref.rs:23:11
2+
--> $DIR/always-inhabited-union-ref.rs:26:11
33
|
44
LL | match uninhab_ref() {
55
| ^^^^^^^^^^^^^
@@ -14,13 +14,13 @@ LL + }
1414
|
1515

1616
error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
17-
--> $DIR/always-inhabited-union-ref.rs:27:11
17+
--> $DIR/always-inhabited-union-ref.rs:30:11
1818
|
1919
LL | match uninhab_union() {
2020
| ^^^^^^^^^^^^^^^
2121
|
2222
note: `Foo` defined here
23-
--> $DIR/always-inhabited-union-ref.rs:10:11
23+
--> $DIR/always-inhabited-union-ref.rs:13:11
2424
|
2525
LL | pub union Foo {
2626
| ^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/always-inhabited-union-ref.rs:7:46
3+
|
4+
LL | #![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #119612 <https://github.com/rust-lang/rust/issues/119612> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
11+
--> $DIR/always-inhabited-union-ref.rs:26:11
12+
|
13+
LL | match uninhab_ref() {
14+
| ^^^^^^^^^^^^^
15+
|
16+
= note: the matched value is of type `&!`
17+
= note: references are always considered inhabited
18+
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
19+
|
20+
LL ~ match uninhab_ref() {
21+
LL + _ => todo!(),
22+
LL + }
23+
|
24+
25+
error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
26+
--> $DIR/always-inhabited-union-ref.rs:30:11
27+
|
28+
LL | match uninhab_union() {
29+
| ^^^^^^^^^^^^^^^
30+
|
31+
note: `Foo` defined here
32+
--> $DIR/always-inhabited-union-ref.rs:13:11
33+
|
34+
LL | pub union Foo {
35+
| ^^^
36+
= note: the matched value is of type `Foo`
37+
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
38+
|
39+
LL ~ match uninhab_union() {
40+
LL + _ => todo!(),
41+
LL + }
42+
|
43+
44+
error: aborting due to 2 previous errors; 1 warning emitted
45+
46+
For more information about this error, try `rustc --explain E0004`.

tests/ui/pattern/usefulness/always-inhabited-union-ref.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
// revisions: min_exhaustive_patterns exhaustive_patterns
2+
13
// The precise semantics of inhabitedness with respect to unions and references is currently
24
// undecided. This test file currently checks a conservative choice.
35

4-
#![feature(exhaustive_patterns)]
6+
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
7+
#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
8+
//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
59
#![feature(never_type)]
6-
710
#![allow(dead_code)]
811
#![allow(unreachable_code)]
912

tests/ui/pattern/usefulness/match-privately-empty.stderr renamed to tests/ui/pattern/usefulness/match-privately-empty.exhaustive_patterns.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
2-
--> $DIR/match-privately-empty.rs:13:11
2+
--> $DIR/match-privately-empty.rs:16:11
33
|
44
LL | match private::DATA {
55
| ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
@@ -12,7 +12,7 @@ note: `Option<Private>` defined here
1212
= note: the matched value is of type `Option<Private>`
1313
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
1414
|
15-
LL ~ }) => {},
15+
LL ~ Some(private::Private { misc: false, .. }) => {},
1616
LL + Some(Private { misc: true, .. }) => todo!()
1717
|
1818

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/match-privately-empty.rs:3:46
3+
|
4+
LL | #![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #119612 <https://github.com/rust-lang/rust/issues/119612> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
11+
--> $DIR/match-privately-empty.rs:16:11
12+
|
13+
LL | match private::DATA {
14+
| ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
15+
|
16+
note: `Option<Private>` defined here
17+
--> $SRC_DIR/core/src/option.rs:LL:COL
18+
::: $SRC_DIR/core/src/option.rs:LL:COL
19+
|
20+
= note: not covered
21+
= note: the matched value is of type `Option<Private>`
22+
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
23+
|
24+
LL ~ Some(private::Private { misc: false, .. }) => {},
25+
LL + Some(Private { misc: true, .. }) => todo!()
26+
|
27+
28+
error: aborting due to 1 previous error; 1 warning emitted
29+
30+
For more information about this error, try `rustc --explain E0004`.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
// revisions: min_exhaustive_patterns exhaustive_patterns
2+
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
3+
#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
4+
//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
15
#![feature(never_type)]
2-
#![feature(exhaustive_patterns)]
36

47
mod private {
58
pub struct Private {
@@ -11,11 +14,8 @@ mod private {
1114

1215
fn main() {
1316
match private::DATA {
14-
//~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
17+
//~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
1518
None => {}
16-
Some(private::Private {
17-
misc: false,
18-
..
19-
}) => {}
19+
Some(private::Private { misc: false, .. }) => {}
2020
}
2121
}

tests/ui/pattern/usefulness/slice_of_empty.stderr renamed to tests/ui/pattern/usefulness/slice_of_empty.exhaustive_patterns.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0004]: non-exhaustive patterns: `&[]` not covered
2-
--> $DIR/slice_of_empty.rs:18:11
2+
--> $DIR/slice_of_empty.rs:22:11
33
|
44
LL | match nevers {
55
| ^^^^^^ pattern `&[]` not covered
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/slice_of_empty.rs:3:46
3+
|
4+
LL | #![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #119612 <https://github.com/rust-lang/rust/issues/119612> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
11+
--> $DIR/slice_of_empty.rs:11:11
12+
|
13+
LL | match nevers {
14+
| ^^^^^^ pattern `&[_, ..]` not covered
15+
|
16+
= note: the matched value is of type `&[!]`
17+
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
18+
|
19+
LL ~ &[] => (),
20+
LL ~ &[_, ..] => todo!(),
21+
|
22+
23+
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
24+
--> $DIR/slice_of_empty.rs:22:11
25+
|
26+
LL | match nevers {
27+
| ^^^^^^ patterns `&[]` and `&[_, _, ..]` not covered
28+
|
29+
= note: the matched value is of type `&[!]`
30+
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
31+
|
32+
LL ~ &[_] => (),
33+
LL ~ &[] | &[_, _, ..] => todo!(),
34+
|
35+
36+
error: aborting due to 2 previous errors; 1 warning emitted
37+
38+
For more information about this error, try `rustc --explain E0004`.

tests/ui/pattern/usefulness/slice_of_empty.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
// revisions: min_exhaustive_patterns exhaustive_patterns
2+
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
3+
#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
4+
//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
15
#![feature(never_type)]
2-
#![feature(exhaustive_patterns)]
36
#![deny(unreachable_patterns)]
47

58
fn main() {}
69

710
fn foo(nevers: &[!]) {
811
match nevers {
12+
//[min_exhaustive_patterns]~^ ERROR non-exhaustive patterns: `&[_, ..]` not covered
913
&[] => (),
1014
};
1115

@@ -16,7 +20,8 @@ fn foo(nevers: &[!]) {
1620
};
1721

1822
match nevers {
19-
//~^ ERROR non-exhaustive patterns: `&[]` not covered
23+
//[exhaustive_patterns]~^ ERROR non-exhaustive patterns: `&[]` not covered
24+
//[min_exhaustive_patterns]~^^ ERROR non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
2025
&[_] => (),
2126
};
2227
}

tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//[pass] check-pass
33
//[fail] check-fail
44
#![feature(never_patterns)]
5-
#![feature(exhaustive_patterns)]
5+
#![feature(min_exhaustive_patterns)]
66
#![allow(incomplete_features)]
77

88
#[derive(Copy, Clone)]
@@ -107,7 +107,7 @@ fn never_pattern_typeck_pass(void: Void) {
107107
}
108108
match (&[] as &[Void]) {
109109
[] => {}
110-
[!],
110+
[!, ..],
111111
}
112112
// Accept on a composite empty type.
113113
match None::<&(u32, Void)> {

tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//[normal] check-pass
33
#![feature(never_patterns)]
44
#![allow(incomplete_features)]
5-
#![cfg_attr(exh_pats, feature(exhaustive_patterns))]
5+
#![cfg_attr(exh_pats, feature(min_exhaustive_patterns))]
66
#![allow(dead_code, unreachable_code)]
77
#![deny(unreachable_patterns)]
88

tests/ui/uninhabited/uninhabited-irrefutable.stderr renamed to tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0005]: refutable pattern in local binding
2-
--> $DIR/uninhabited-irrefutable.rs:29:9
2+
--> $DIR/uninhabited-irrefutable.rs:32:9
33
|
44
LL | let Foo::D(_y, _z) = x;
55
| ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
66
|
77
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
99
note: `Foo` defined here
10-
--> $DIR/uninhabited-irrefutable.rs:18:6
10+
--> $DIR/uninhabited-irrefutable.rs:21:6
1111
|
1212
LL | enum Foo {
1313
| ^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0005]: refutable pattern in local binding
2+
--> $DIR/uninhabited-irrefutable.rs:32:9
3+
|
4+
LL | let Foo::D(_y, _z) = x;
5+
| ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
6+
|
7+
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
8+
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
9+
note: `Foo` defined here
10+
--> $DIR/uninhabited-irrefutable.rs:21:6
11+
|
12+
LL | enum Foo {
13+
| ^^^
14+
LL |
15+
LL | A(foo::SecretlyEmpty),
16+
| - not covered
17+
= note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
18+
= note: the matched value is of type `Foo`
19+
help: you might want to use `let else` to handle the variant that isn't matched
20+
|
21+
LL | let Foo::D(_y, _z) = x else { todo!() };
22+
| ++++++++++++++++
23+
24+
error: aborting due to 1 previous error
25+
26+
For more information about this error, try `rustc --explain E0005`.

tests/ui/uninhabited/uninhabited-irrefutable.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
// revisions: min_exhaustive_patterns exhaustive_patterns
2+
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
3+
#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
4+
#![cfg_attr(min_exhaustive_patterns, allow(incomplete_features))]
15
#![feature(never_type)]
2-
#![feature(exhaustive_patterns)]
36

47
mod foo {
58
pub struct SecretlyEmpty {

0 commit comments

Comments
 (0)