diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-11-29 12:34:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-29 12:34:47 +0100 |
| commit | c03f8917ee45255166916cdc8b9aa1f6f8a98fdc (patch) | |
| tree | 7fedd712bd38a5ed6042be8a84a4eaad627dd981 /tests/ui/pattern | |
| parent | ec1f21cb0483c40329b54c10b19c0e6220f5e51d (diff) | |
| parent | a3838c855064f55485147c66e0e50b039875613e (diff) | |
| download | rust-c03f8917ee45255166916cdc8b9aa1f6f8a98fdc.tar.gz rust-c03f8917ee45255166916cdc8b9aa1f6f8a98fdc.zip | |
Rollup merge of #118157 - Nadrieril:never_pat-feature-gate, r=compiler-errors
Add `never_patterns` feature gate This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment. `@scottmcm` has agreed to be my lang-team liaison for this experiment.
Diffstat (limited to 'tests/ui/pattern')
| -rw-r--r-- | tests/ui/pattern/never_patterns.rs | 99 | ||||
| -rw-r--r-- | tests/ui/pattern/never_patterns.stderr | 51 |
2 files changed, 150 insertions, 0 deletions
diff --git a/tests/ui/pattern/never_patterns.rs b/tests/ui/pattern/never_patterns.rs new file mode 100644 index 00000000000..e2e17e0e9a7 --- /dev/null +++ b/tests/ui/pattern/never_patterns.rs @@ -0,0 +1,99 @@ +#![feature(never_patterns)] +#![allow(incomplete_features)] + +enum Void {} + +fn main() {} + +// The classic use for empty types. +fn safe_unwrap_result<T>(res: Result<T, Void>) { + let Ok(_x) = res; + // FIXME(never_patterns): These should be allowed + let (Ok(_x) | Err(!)) = &res; + //~^ ERROR: is not bound in all patterns + let (Ok(_x) | Err(&!)) = res.as_ref(); + //~^ ERROR: is not bound in all patterns +} + +// Check we only accept `!` where we want to. +fn never_pattern_location(void: Void) { + // FIXME(never_patterns): Don't accept on a non-empty type. + match Some(0) { + None => {} + Some(!) => {} + } + // FIXME(never_patterns): Don't accept on an arbitrary type, even if there are no more branches. + match () { + () => {} + ! => {} + } + // FIXME(never_patterns): Don't accept even on an empty branch. + match None::<Void> { + None => {} + ! => {} + } + // FIXME(never_patterns): Let alone if the emptiness is behind a reference. + match None::<&Void> { + None => {} + ! => {} + } + // Participate in match ergonomics. + match &void { + ! => {} + } + match &&void { + ! => {} + } + match &&void { + &! => {} + } + match &None::<Void> { + None => {} + Some(!) => {} + } + match None::<&Void> { + None => {} + Some(!) => {} + } + // Accept on a composite empty type. + match None::<&(u32, Void)> { + None => {} + Some(&!) => {} + } + // Accept on an simple empty type. + match None::<Void> { + None => {} + Some(!) => {} + } + match None::<&Void> { + None => {} + Some(&!) => {} + } + match None::<&(u32, Void)> { + None => {} + Some(&(_, !)) => {} + } +} + +fn never_and_bindings() { + let x: Result<bool, &(u32, Void)> = Ok(false); + + // FIXME(never_patterns): Never patterns in or-patterns don't need to share the same bindings. + match x { + Ok(_x) | Err(&!) => {} + //~^ ERROR: is not bound in all patterns + } + let (Ok(_x) | Err(&!)) = x; + //~^ ERROR: is not bound in all patterns + + // FIXME(never_patterns): A never pattern mustn't have bindings. + match x { + Ok(_) => {} + Err(&(_b, !)) => {} + } + match x { + Ok(_a) | Err(&(_b, !)) => {} + //~^ ERROR: is not bound in all patterns + //~| ERROR: is not bound in all patterns + } +} diff --git a/tests/ui/pattern/never_patterns.stderr b/tests/ui/pattern/never_patterns.stderr new file mode 100644 index 00000000000..11e50debfd3 --- /dev/null +++ b/tests/ui/pattern/never_patterns.stderr @@ -0,0 +1,51 @@ +error[E0408]: variable `_x` is not bound in all patterns + --> $DIR/never_patterns.rs:12:19 + | +LL | let (Ok(_x) | Err(!)) = &res; + | -- ^^^^^^ pattern doesn't bind `_x` + | | + | variable not in all patterns + +error[E0408]: variable `_x` is not bound in all patterns + --> $DIR/never_patterns.rs:14:19 + | +LL | let (Ok(_x) | Err(&!)) = res.as_ref(); + | -- ^^^^^^^ pattern doesn't bind `_x` + | | + | variable not in all patterns + +error[E0408]: variable `_x` is not bound in all patterns + --> $DIR/never_patterns.rs:83:18 + | +LL | Ok(_x) | Err(&!) => {} + | -- ^^^^^^^ pattern doesn't bind `_x` + | | + | variable not in all patterns + +error[E0408]: variable `_x` is not bound in all patterns + --> $DIR/never_patterns.rs:86:19 + | +LL | let (Ok(_x) | Err(&!)) = x; + | -- ^^^^^^^ pattern doesn't bind `_x` + | | + | variable not in all patterns + +error[E0408]: variable `_b` is not bound in all patterns + --> $DIR/never_patterns.rs:95:9 + | +LL | Ok(_a) | Err(&(_b, !)) => {} + | ^^^^^^ -- variable not in all patterns + | | + | pattern doesn't bind `_b` + +error[E0408]: variable `_a` is not bound in all patterns + --> $DIR/never_patterns.rs:95:18 + | +LL | Ok(_a) | Err(&(_b, !)) => {} + | -- ^^^^^^^^^^^^^ pattern doesn't bind `_a` + | | + | variable not in all patterns + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0408`. |
