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 a8cc4cf

Browse files
committedDec 11, 2023
min_exhaustive_patterns
1 parent 21cce21 commit a8cc4cf

File tree

10 files changed

+783
-146
lines changed

10 files changed

+783
-146
lines changed
 

‎compiler/rustc_feature/src/unstable.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,9 @@ declare_features! (
512512
(unstable, macro_metavar_expr, "1.61.0", Some(83527)),
513513
/// Allows `#[marker]` on certain traits allowing overlapping implementations.
514514
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
515+
/// Allows exhaustive pattern matching on types that contain uninhabited types in cases that are
516+
/// unambiguously sound.
517+
(unstable, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", None),
515518
/// A minimal, sound subset of specialization intended to be used by the
516519
/// standard library until the soundness issues with specialization
517520
/// are fixed.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
295295
fn is_known_valid_scrutinee(&self, scrutinee: &Expr<'tcx>) -> bool {
296296
use ExprKind::*;
297297
match &scrutinee.kind {
298-
// Both pointers and references can validly point to a place with invalid data.
298+
// Pointers can validly point to a place with invalid data. It is undecided whether
299+
// references can too, so we conservatively assume they can.
299300
Deref { .. } => false,
300301
// Inherit validity of the parent place, unless the parent is an union.
301302
Field { lhs, .. } => {

‎compiler/rustc_pattern_analysis/src/constructor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ impl ConstructorSet {
976976
// In the absence of the `exhaustive_patterns` feature however, we don't count nested empty
977977
// types as empty. Only non-nested `!` or `enum Foo {}` are considered empty.
978978
if !pcx.cx.tcx.features().exhaustive_patterns
979+
&& !pcx.cx.tcx.features().min_exhaustive_patterns
979980
&& !(pcx.is_top_level && matches!(self, Self::NoConstructors))
980981
{
981982
// Treat all missing constructors as nonempty.

‎compiler/rustc_pattern_analysis/src/cx.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ impl<'p, 'tcx> MatchCheckCtxt<'p, 'tcx> {
8989
// `field.ty()` doesn't normalize after substituting.
9090
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
9191
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
92-
let is_uninhabited = cx.tcx.features().exhaustive_patterns && cx.is_uninhabited(ty);
92+
let is_uninhabited = (cx.tcx.features().exhaustive_patterns
93+
|| cx.tcx.features().min_exhaustive_patterns)
94+
&& cx.is_uninhabited(ty);
9395

9496
if is_uninhabited && (!is_visible || is_non_exhaustive) {
9597
None

‎compiler/rustc_pattern_analysis/src/usefulness.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,17 +1186,23 @@ fn compute_exhaustiveness_and_usefulness<'p, 'tcx>(
11861186

11871187
debug!("ty: {ty:?}");
11881188
let pcx = &PatCtxt { cx, ty, is_top_level };
1189+
let ctors_for_ty = &cx.ctors_for_ty(ty);
1190+
let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. }); // For diagnostics.
11891191

11901192
// Whether the place/column we are inspecting is known to contain valid data.
1191-
let place_validity = matrix.place_validity[0];
1192-
// For backwards compability we allow omitting some empty arms that we ideally shouldn't.
1193-
let place_validity = place_validity.allow_omitting_side_effecting_arms();
1193+
let mut place_validity = matrix.place_validity[0];
1194+
if !pcx.cx.tcx.features().min_exhaustive_patterns
1195+
|| (is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors))
1196+
{
1197+
// For backwards compability we allow omitting some empty arms that we ideally shouldn't.
1198+
place_validity = place_validity.allow_omitting_side_effecting_arms();
1199+
}
11941200

11951201
// Analyze the constructors present in this column.
11961202
let ctors = matrix.heads().map(|p| p.ctor());
1197-
let ctors_for_ty = &cx.ctors_for_ty(ty);
1198-
let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. }); // For diagnostics.
11991203
let split_set = ctors_for_ty.split(pcx, ctors);
1204+
1205+
// Decide what constructors to report.
12001206
let all_missing = split_set.present.is_empty();
12011207

12021208
// Build the set of constructors we will specialize with. It must cover the whole type.

‎compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,7 @@ symbols! {
10151015
min_const_fn,
10161016
min_const_generics,
10171017
min_const_unsafe_fn,
1018+
min_exhaustive_patterns,
10181019
min_specialization,
10191020
min_type_alias_impl_trait,
10201021
minnumf32,

‎tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
error: unreachable pattern
2-
--> $DIR/empty-types.rs:47:9
2+
--> $DIR/empty-types.rs:48:9
33
|
44
LL | _ => {}
55
| ^
66
|
77
note: the lint level is defined here
8-
--> $DIR/empty-types.rs:13:9
8+
--> $DIR/empty-types.rs:14:9
99
|
1010
LL | #![deny(unreachable_patterns)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

1313
error: unreachable pattern
14-
--> $DIR/empty-types.rs:50:9
14+
--> $DIR/empty-types.rs:51:9
1515
|
1616
LL | _x => {}
1717
| ^^
1818

1919
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
20-
--> $DIR/empty-types.rs:54:11
20+
--> $DIR/empty-types.rs:55:11
2121
|
2222
LL | match ref_never {}
2323
| ^^^^^^^^^
@@ -32,31 +32,31 @@ LL + }
3232
|
3333

3434
error: unreachable pattern
35-
--> $DIR/empty-types.rs:69:9
35+
--> $DIR/empty-types.rs:70:9
3636
|
3737
LL | (_, _) => {}
3838
| ^^^^^^
3939

4040
error: unreachable pattern
41-
--> $DIR/empty-types.rs:76:9
41+
--> $DIR/empty-types.rs:77:9
4242
|
4343
LL | _ => {}
4444
| ^
4545

4646
error: unreachable pattern
47-
--> $DIR/empty-types.rs:79:9
47+
--> $DIR/empty-types.rs:80:9
4848
|
4949
LL | (_, _) => {}
5050
| ^^^^^^
5151

5252
error: unreachable pattern
53-
--> $DIR/empty-types.rs:83:9
53+
--> $DIR/empty-types.rs:84:9
5454
|
5555
LL | _ => {}
5656
| ^
5757

5858
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
59-
--> $DIR/empty-types.rs:87:11
59+
--> $DIR/empty-types.rs:88:11
6060
|
6161
LL | match res_u32_never {}
6262
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@@ -75,19 +75,19 @@ LL + }
7575
|
7676

7777
error: unreachable pattern
78-
--> $DIR/empty-types.rs:95:9
78+
--> $DIR/empty-types.rs:96:9
7979
|
8080
LL | Err(_) => {}
8181
| ^^^^^^
8282

8383
error: unreachable pattern
84-
--> $DIR/empty-types.rs:100:9
84+
--> $DIR/empty-types.rs:101:9
8585
|
8686
LL | Err(_) => {}
8787
| ^^^^^^
8888

8989
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
90-
--> $DIR/empty-types.rs:97:11
90+
--> $DIR/empty-types.rs:98:11
9191
|
9292
LL | match res_u32_never {
9393
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
@@ -105,7 +105,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
105105
|
106106

107107
error[E0005]: refutable pattern in local binding
108-
--> $DIR/empty-types.rs:104:9
108+
--> $DIR/empty-types.rs:105:9
109109
|
110110
LL | let Ok(_x) = res_u32_never.as_ref();
111111
| ^^^^^^ pattern `Err(_)` not covered
@@ -119,121 +119,121 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
119119
| ++++++++++++++++
120120

121121
error: unreachable pattern
122-
--> $DIR/empty-types.rs:115:9
122+
--> $DIR/empty-types.rs:116:9
123123
|
124124
LL | _ => {}
125125
| ^
126126

127127
error: unreachable pattern
128-
--> $DIR/empty-types.rs:119:9
128+
--> $DIR/empty-types.rs:120:9
129129
|
130130
LL | Ok(_) => {}
131131
| ^^^^^
132132

133133
error: unreachable pattern
134-
--> $DIR/empty-types.rs:122:9
134+
--> $DIR/empty-types.rs:123:9
135135
|
136136
LL | Ok(_) => {}
137137
| ^^^^^
138138

139139
error: unreachable pattern
140-
--> $DIR/empty-types.rs:123:9
140+
--> $DIR/empty-types.rs:124:9
141141
|
142142
LL | _ => {}
143143
| ^
144144

145145
error: unreachable pattern
146-
--> $DIR/empty-types.rs:126:9
146+
--> $DIR/empty-types.rs:127:9
147147
|
148148
LL | Ok(_) => {}
149149
| ^^^^^
150150

151151
error: unreachable pattern
152-
--> $DIR/empty-types.rs:127:9
152+
--> $DIR/empty-types.rs:128:9
153153
|
154154
LL | Err(_) => {}
155155
| ^^^^^^
156156

157157
error: unreachable pattern
158-
--> $DIR/empty-types.rs:136:13
158+
--> $DIR/empty-types.rs:137:13
159159
|
160160
LL | _ => {}
161161
| ^
162162

163163
error: unreachable pattern
164-
--> $DIR/empty-types.rs:139:13
164+
--> $DIR/empty-types.rs:140:13
165165
|
166166
LL | _ if false => {}
167167
| ^
168168

169169
error: unreachable pattern
170-
--> $DIR/empty-types.rs:148:13
170+
--> $DIR/empty-types.rs:149:13
171171
|
172172
LL | Some(_) => {}
173173
| ^^^^^^^
174174

175175
error: unreachable pattern
176-
--> $DIR/empty-types.rs:152:13
176+
--> $DIR/empty-types.rs:153:13
177177
|
178178
LL | _ => {}
179179
| ^
180180

181181
error: unreachable pattern
182-
--> $DIR/empty-types.rs:204:13
182+
--> $DIR/empty-types.rs:205:13
183183
|
184184
LL | _ => {}
185185
| ^
186186

187187
error: unreachable pattern
188-
--> $DIR/empty-types.rs:209:13
188+
--> $DIR/empty-types.rs:210:13
189189
|
190190
LL | _ => {}
191191
| ^
192192

193193
error: unreachable pattern
194-
--> $DIR/empty-types.rs:214:13
194+
--> $DIR/empty-types.rs:215:13
195195
|
196196
LL | _ => {}
197197
| ^
198198

199199
error: unreachable pattern
200-
--> $DIR/empty-types.rs:219:13
200+
--> $DIR/empty-types.rs:220:13
201201
|
202202
LL | _ => {}
203203
| ^
204204

205205
error: unreachable pattern
206-
--> $DIR/empty-types.rs:225:13
206+
--> $DIR/empty-types.rs:226:13
207207
|
208208
LL | _ => {}
209209
| ^
210210

211211
error: unreachable pattern
212-
--> $DIR/empty-types.rs:284:9
212+
--> $DIR/empty-types.rs:285:9
213213
|
214214
LL | _ => {}
215215
| ^
216216

217217
error: unreachable pattern
218-
--> $DIR/empty-types.rs:287:9
218+
--> $DIR/empty-types.rs:288:9
219219
|
220220
LL | (_, _) => {}
221221
| ^^^^^^
222222

223223
error: unreachable pattern
224-
--> $DIR/empty-types.rs:290:9
224+
--> $DIR/empty-types.rs:291:9
225225
|
226226
LL | Ok(_) => {}
227227
| ^^^^^
228228

229229
error: unreachable pattern
230-
--> $DIR/empty-types.rs:291:9
230+
--> $DIR/empty-types.rs:292:9
231231
|
232232
LL | Err(_) => {}
233233
| ^^^^^^
234234

235235
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
236-
--> $DIR/empty-types.rs:323:11
236+
--> $DIR/empty-types.rs:324:11
237237
|
238238
LL | match slice_never {}
239239
| ^^^^^^^^^^^
@@ -247,7 +247,7 @@ LL + }
247247
|
248248

249249
error[E0004]: non-exhaustive patterns: `&[]` not covered
250-
--> $DIR/empty-types.rs:334:11
250+
--> $DIR/empty-types.rs:335:11
251251
|
252252
LL | match slice_never {
253253
| ^^^^^^^^^^^ pattern `&[]` not covered
@@ -260,7 +260,7 @@ LL + &[] => todo!()
260260
|
261261

262262
error[E0004]: non-exhaustive patterns: `&[]` not covered
263-
--> $DIR/empty-types.rs:347:11
263+
--> $DIR/empty-types.rs:348:11
264264
|
265265
LL | match slice_never {
266266
| ^^^^^^^^^^^ pattern `&[]` not covered
@@ -274,7 +274,7 @@ LL + &[] => todo!()
274274
|
275275

276276
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
277-
--> $DIR/empty-types.rs:353:11
277+
--> $DIR/empty-types.rs:354:11
278278
|
279279
LL | match *slice_never {}
280280
| ^^^^^^^^^^^^
@@ -288,25 +288,25 @@ LL + }
288288
|
289289

290290
error: unreachable pattern
291-
--> $DIR/empty-types.rs:363:9
291+
--> $DIR/empty-types.rs:364:9
292292
|
293293
LL | _ => {}
294294
| ^
295295

296296
error: unreachable pattern
297-
--> $DIR/empty-types.rs:366:9
297+
--> $DIR/empty-types.rs:367:9
298298
|
299299
LL | [_, _, _] => {}
300300
| ^^^^^^^^^
301301

302302
error: unreachable pattern
303-
--> $DIR/empty-types.rs:369:9
303+
--> $DIR/empty-types.rs:370:9
304304
|
305305
LL | [_, ..] => {}
306306
| ^^^^^^^
307307

308308
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
309-
--> $DIR/empty-types.rs:383:11
309+
--> $DIR/empty-types.rs:384:11
310310
|
311311
LL | match array_0_never {}
312312
| ^^^^^^^^^^^^^
@@ -320,13 +320,13 @@ LL + }
320320
|
321321

322322
error: unreachable pattern
323-
--> $DIR/empty-types.rs:390:9
323+
--> $DIR/empty-types.rs:391:9
324324
|
325325
LL | _ => {}
326326
| ^
327327

328328
error[E0004]: non-exhaustive patterns: `[]` not covered
329-
--> $DIR/empty-types.rs:392:11
329+
--> $DIR/empty-types.rs:393:11
330330
|
331331
LL | match array_0_never {
332332
| ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -340,49 +340,49 @@ LL + [] => todo!()
340340
|
341341

342342
error: unreachable pattern
343-
--> $DIR/empty-types.rs:411:9
343+
--> $DIR/empty-types.rs:412:9
344344
|
345345
LL | Some(_) => {}
346346
| ^^^^^^^
347347

348348
error: unreachable pattern
349-
--> $DIR/empty-types.rs:416:9
349+
--> $DIR/empty-types.rs:417:9
350350
|
351351
LL | Some(_a) => {}
352352
| ^^^^^^^^
353353

354354
error: unreachable pattern
355-
--> $DIR/empty-types.rs:421:9
355+
--> $DIR/empty-types.rs:422:9
356356
|
357357
LL | _ => {}
358358
| ^
359359

360360
error: unreachable pattern
361-
--> $DIR/empty-types.rs:426:9
361+
--> $DIR/empty-types.rs:427:9
362362
|
363363
LL | _a => {}
364364
| ^^
365365

366366
error: unreachable pattern
367-
--> $DIR/empty-types.rs:598:9
367+
--> $DIR/empty-types.rs:599:9
368368
|
369369
LL | _ => {}
370370
| ^
371371

372372
error: unreachable pattern
373-
--> $DIR/empty-types.rs:601:9
373+
--> $DIR/empty-types.rs:602:9
374374
|
375375
LL | _x => {}
376376
| ^^
377377

378378
error: unreachable pattern
379-
--> $DIR/empty-types.rs:604:9
379+
--> $DIR/empty-types.rs:605:9
380380
|
381381
LL | _ if false => {}
382382
| ^
383383

384384
error: unreachable pattern
385-
--> $DIR/empty-types.rs:607:9
385+
--> $DIR/empty-types.rs:608:9
386386
|
387387
LL | _x if false => {}
388388
| ^^

‎tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr

Lines changed: 621 additions & 0 deletions
Large diffs are not rendered by default.

‎tests/ui/pattern/usefulness/empty-types.normal.stderr

Lines changed: 49 additions & 49 deletions
Large diffs are not rendered by default.

‎tests/ui/pattern/usefulness/empty-types.rs

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// revisions: normal exhaustive_patterns
1+
// revisions: normal min_exh_pats exhaustive_patterns
22
//
33
// This tests correct handling of empty types in exhaustiveness checking.
44
//
@@ -9,6 +9,7 @@
99
// This feature is useful to avoid `!` falling back to `()` all the time.
1010
#![feature(never_type_fallback)]
1111
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
12+
#![cfg_attr(min_exh_pats, feature(min_exhaustive_patterns))]
1213
#![allow(dead_code, unreachable_code)]
1314
#![deny(unreachable_patterns)]
1415

@@ -66,17 +67,17 @@ fn basic(x: NeverBundle) {
6667
match tuple_half_never {}
6768
//[normal]~^ ERROR non-empty
6869
match tuple_half_never {
69-
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
70+
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
7071
}
7172

7273
let tuple_never: (!, !) = x.tuple_never;
7374
match tuple_never {}
7475
//[normal]~^ ERROR non-empty
7576
match tuple_never {
76-
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
77+
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
7778
}
7879
match tuple_never {
79-
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
80+
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
8081
}
8182
match tuple_never.0 {}
8283
match tuple_never.0 {
@@ -92,12 +93,12 @@ fn basic(x: NeverBundle) {
9293
}
9394
match res_u32_never {
9495
Ok(_) => {}
95-
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
96+
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
9697
}
9798
match res_u32_never {
9899
//~^ ERROR non-exhaustive
99100
Ok(0) => {}
100-
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
101+
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
101102
}
102103
let Ok(_x) = res_u32_never;
103104
//[normal]~^ ERROR refutable
@@ -106,25 +107,25 @@ fn basic(x: NeverBundle) {
106107
// Non-obvious difference: here there's an implicit dereference in the patterns, which makes the
107108
// inner place !known_valid. `exhaustive_patterns` ignores this.
108109
let Ok(_x) = &res_u32_never;
109-
//[normal]~^ ERROR refutable
110+
//[normal,min_exh_pats]~^ ERROR refutable
110111

111112
let result_never: Result<!, !> = x.result_never;
112113
match result_never {}
113114
//[normal]~^ ERROR non-exhaustive
114115
match result_never {
115-
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
116+
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
116117
}
117118
match result_never {
118119
//[normal]~^ ERROR non-exhaustive
119-
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
120+
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
120121
}
121122
match result_never {
122-
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
123-
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
123+
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
124+
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
124125
}
125126
match result_never {
126-
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
127-
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
127+
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
128+
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
128129
}
129130
}
130131

@@ -145,11 +146,11 @@ fn void_same_as_never(x: NeverBundle) {
145146
}
146147
match opt_void {
147148
None => {}
148-
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
149+
Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
149150
}
150151
match opt_void {
151152
None => {}
152-
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
153+
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
153154
}
154155

155156
let ref_void: &Void = &x.void;
@@ -159,7 +160,7 @@ fn void_same_as_never(x: NeverBundle) {
159160
}
160161
let ref_opt_void: &Option<Void> = &None;
161162
match *ref_opt_void {
162-
//[normal]~^ ERROR non-exhaustive
163+
//[normal,min_exh_pats]~^ ERROR non-exhaustive
163164
None => {}
164165
}
165166
match *ref_opt_void {
@@ -284,11 +285,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
284285
_ => {} //~ ERROR unreachable pattern
285286
}
286287
match tuple_never {
287-
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
288+
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
288289
}
289290
match result_never {
290-
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
291-
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
291+
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
292+
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
292293
}
293294

294295
// These should be considered !known_valid and not warn unreachable.
@@ -309,21 +310,21 @@ fn invalid_empty_match(bundle: NeverBundle) {
309310
match *x {}
310311

311312
let x: &(u32, !) = &bundle.tuple_half_never;
312-
match *x {} //[normal]~ ERROR non-exhaustive
313+
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
313314
let x: &(!, !) = &bundle.tuple_never;
314-
match *x {} //[normal]~ ERROR non-exhaustive
315+
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
315316
let x: &Result<!, !> = &bundle.result_never;
316-
match *x {} //[normal]~ ERROR non-exhaustive
317+
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
317318
let x: &[!; 3] = &bundle.array_3_never;
318-
match *x {} //[normal]~ ERROR non-exhaustive
319+
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
319320
}
320321

321322
fn arrays_and_slices(x: NeverBundle) {
322323
let slice_never: &[!] = &[];
323324
match slice_never {}
324325
//~^ ERROR non-empty
325326
match slice_never {
326-
//[normal]~^ ERROR not covered
327+
//[normal,min_exh_pats]~^ ERROR not covered
327328
[] => {}
328329
}
329330
match slice_never {
@@ -332,7 +333,7 @@ fn arrays_and_slices(x: NeverBundle) {
332333
[_, _, ..] => {}
333334
}
334335
match slice_never {
335-
//[normal]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
336+
//[normal,min_exh_pats]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
336337
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
337338
[_, _, _, ..] => {}
338339
}
@@ -345,7 +346,7 @@ fn arrays_and_slices(x: NeverBundle) {
345346
_x => {}
346347
}
347348
match slice_never {
348-
//[normal]~^ ERROR `&[]` and `&[_, ..]` not covered
349+
//[normal,min_exh_pats]~^ ERROR `&[]` and `&[_, ..]` not covered
349350
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
350351
&[..] if false => {}
351352
}
@@ -360,13 +361,13 @@ fn arrays_and_slices(x: NeverBundle) {
360361
match array_3_never {}
361362
//[normal]~^ ERROR non-empty
362363
match array_3_never {
363-
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
364+
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
364365
}
365366
match array_3_never {
366-
[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
367+
[_, _, _] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
367368
}
368369
match array_3_never {
369-
[_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
370+
[_, ..] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
370371
}
371372

372373
let ref_array_3_never: &[!; 3] = &array_3_never;
@@ -408,22 +409,22 @@ fn bindings(x: NeverBundle) {
408409
match opt_never {
409410
None => {}
410411
// !useful, !reachable
411-
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
412+
Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
412413
}
413414
match opt_never {
414415
None => {}
415416
// !useful, !reachable
416-
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
417+
Some(_a) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
417418
}
418419
match opt_never {
419420
None => {}
420421
// !useful, !reachable
421-
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
422+
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
422423
}
423424
match opt_never {
424425
None => {}
425426
// !useful, !reachable
426-
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
427+
_a => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
427428
}
428429

429430
// The scrutinee is known_valid, but under the `&` isn't anymore.
@@ -444,7 +445,7 @@ fn bindings(x: NeverBundle) {
444445
&_a => {}
445446
}
446447
match ref_opt_never {
447-
//[normal]~^ ERROR non-exhaustive
448+
//[normal,min_exh_pats]~^ ERROR non-exhaustive
448449
&None => {}
449450
}
450451
match ref_opt_never {
@@ -485,7 +486,7 @@ fn bindings(x: NeverBundle) {
485486
ref _a => {}
486487
}
487488
match *ref_opt_never {
488-
//[normal]~^ ERROR non-exhaustive
489+
//[normal,min_exh_pats]~^ ERROR non-exhaustive
489490
None => {}
490491
}
491492
match *ref_opt_never {
@@ -533,7 +534,7 @@ fn bindings(x: NeverBundle) {
533534

534535
let ref_res_never: &Result<!, !> = &x.result_never;
535536
match *ref_res_never {
536-
//[normal]~^ ERROR non-exhaustive
537+
//[normal,min_exh_pats]~^ ERROR non-exhaustive
537538
// useful, reachable
538539
Ok(_) => {}
539540
}
@@ -544,7 +545,7 @@ fn bindings(x: NeverBundle) {
544545
_ => {}
545546
}
546547
match *ref_res_never {
547-
//[normal]~^ ERROR non-exhaustive
548+
//[normal,min_exh_pats]~^ ERROR non-exhaustive
548549
// useful, !reachable
549550
Ok(_a) => {}
550551
}
@@ -563,7 +564,7 @@ fn bindings(x: NeverBundle) {
563564

564565
let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never;
565566
match *ref_tuple_half_never {}
566-
//[normal]~^ ERROR non-empty
567+
//[normal,min_exh_pats]~^ ERROR non-empty
567568
match *ref_tuple_half_never {
568569
// useful, reachable
569570
(_, _) => {}
@@ -614,6 +615,7 @@ fn guards_and_validity(x: NeverBundle) {
614615
// useful, reachable
615616
_ => {}
616617
}
618+
617619
// Now the madness commences. The guard caused a load of the value thus asserting validity. So
618620
// there's no invalid value for `_` to catch. So the second pattern is unreachable despite the
619621
// guard not being taken.
@@ -629,7 +631,7 @@ fn guards_and_validity(x: NeverBundle) {
629631
_a if false => {}
630632
}
631633
match ref_never {
632-
//[normal]~^ ERROR non-exhaustive
634+
//[normal,min_exh_pats]~^ ERROR non-exhaustive
633635
// useful, !reachable
634636
&_a if false => {}
635637
}
@@ -657,7 +659,7 @@ fn diagnostics_subtlety(x: NeverBundle) {
657659
// Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`.
658660
let x: &Option<Result<!, !>> = &None;
659661
match *x {
660-
//[normal]~^ ERROR `Some(_)` not covered
662+
//[normal,min_exh_pats]~^ ERROR `Some(_)` not covered
661663
None => {}
662664
}
663665
}

0 commit comments

Comments
 (0)
Please sign in to comment.