From a3838c855064f55485147c66e0e50b039875613e Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 22 Nov 2023 02:30:43 +0100 Subject: Add `never_patterns` feature gate --- tests/ui/pattern/never_patterns.rs | 99 ++++++++++++++++++++++++++++++++++ tests/ui/pattern/never_patterns.stderr | 51 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/ui/pattern/never_patterns.rs create mode 100644 tests/ui/pattern/never_patterns.stderr (limited to 'tests/ui/pattern') 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(res: Result) { + 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:: { + 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:: { + 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:: { + None => {} + Some(!) => {} + } + match None::<&Void> { + None => {} + Some(&!) => {} + } + match None::<&(u32, Void)> { + None => {} + Some(&(_, !)) => {} + } +} + +fn never_and_bindings() { + let x: Result = 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`. -- cgit 1.4.1-3-g733a5