From f35432e1889a4361388adf514634b122aefa746b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 18 Aug 2019 23:53:08 +0200 Subject: [PATCH] or-patterns: add syntactic tests. --- .../or-patterns/or-patterns-syntactic-fail.rs | 56 +++++++++++++ .../or-patterns-syntactic-fail.stderr | 75 ++++++++++++++++++ .../or-patterns/or-patterns-syntactic-pass.rs | 78 +++++++++++++++++++ .../or-patterns-syntactic-pass.stderr | 8 ++ 4 files changed, 217 insertions(+) create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-fail.rs create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass.rs create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs new file mode 100644 index 00000000000..43c9214bd98 --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs @@ -0,0 +1,56 @@ +// Test some cases where or-patterns may ostensibly be allowed but are in fact not. +// This is not a semantic test. We only test parsing. + +#![feature(or_patterns)] +//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash + +fn main() {} + +// Test the `pat` macro fragment parser: +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!(p | q); //~ ERROR no rules expected the token `|` +accept_pat!(| p | q); //~ ERROR no rules expected the token `|` + +// Non-macro tests: + +enum E { A, B } +use E::*; + +fn no_top_level_or_patterns() { + // We do *not* allow or-patterns at the top level of lambdas... + let _ = |A | B: E| (); //~ ERROR binary operation `|` cannot be applied to type `E` + // -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`. + + // ...and for now neither do we allow or-patterns at the top level of functions. + fn fun(A | B: E) {} //~ ERROR expected one of `:` or `@`, found `|` +} + +// We also do not allow a leading `|` when not in a top level position: + +#[cfg(FALSE)] +fn no_leading_parens() { + let ( | A | B); //~ ERROR expected pattern, found `|` +} + +#[cfg(FALSE)] +fn no_leading_tuple() { + let ( | A | B,); //~ ERROR expected pattern, found `|` +} + +#[cfg(FALSE)] +fn no_leading_slice() { + let [ | A | B ]; //~ ERROR expected pattern, found `|` +} + +#[cfg(FALSE)] +fn no_leading_tuple_struct() { + let TS( | A | B ); //~ ERROR expected pattern, found `|` +} + +#[cfg(FALSE)] +fn no_leading_struct() { + let NS { f: | A | B }; //~ ERROR expected pattern, found `|` +} diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr new file mode 100644 index 00000000000..809ff272f62 --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr @@ -0,0 +1,75 @@ +error: expected one of `:` or `@`, found `|` + --> $DIR/or-patterns-syntactic-fail.rs:28:14 + | +LL | fn fun(A | B: E) {} + | ^ expected one of `:` or `@` here + +error: expected pattern, found `|` + --> $DIR/or-patterns-syntactic-fail.rs:35:11 + | +LL | let ( | A | B); + | ^ expected pattern + +error: expected pattern, found `|` + --> $DIR/or-patterns-syntactic-fail.rs:40:11 + | +LL | let ( | A | B,); + | ^ expected pattern + +error: expected pattern, found `|` + --> $DIR/or-patterns-syntactic-fail.rs:45:11 + | +LL | let [ | A | B ]; + | ^ expected pattern + +error: expected pattern, found `|` + --> $DIR/or-patterns-syntactic-fail.rs:50:13 + | +LL | let TS( | A | B ); + | ^ expected pattern + +error: expected pattern, found `|` + --> $DIR/or-patterns-syntactic-fail.rs:55:17 + | +LL | let NS { f: | A | B }; + | ^ expected pattern + +error: no rules expected the token `|` + --> $DIR/or-patterns-syntactic-fail.rs:14:15 + | +LL | macro_rules! accept_pat { + | ----------------------- when calling this macro +... +LL | accept_pat!(p | q); + | ^ no rules expected this token in macro call + +error: no rules expected the token `|` + --> $DIR/or-patterns-syntactic-fail.rs:15:13 + | +LL | macro_rules! accept_pat { + | ----------------------- when calling this macro +... +LL | accept_pat!(| p | q); + | ^ no rules expected this token in macro call + +warning: the feature `or_patterns` is incomplete and may cause the compiler to crash + --> $DIR/or-patterns-syntactic-fail.rs:4:12 + | +LL | #![feature(or_patterns)] + | ^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0369]: binary operation `|` cannot be applied to type `E` + --> $DIR/or-patterns-syntactic-fail.rs:24:22 + | +LL | let _ = |A | B: E| (); + | ----^ -- () + | | + | E + | + = note: an implementation of `std::ops::BitOr` might be missing for `E` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs new file mode 100644 index 00000000000..5fe72caf9c1 --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs @@ -0,0 +1,78 @@ +// Here we test all the places `|` is *syntactically* allowed. +// This is not a semantic test. We only test parsing. + +// check-pass + +#![feature(or_patterns)] + +fn main() {} + +// Test the `pat` macro fragment parser: +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!((p | q)); +accept_pat!((p | q,)); +accept_pat!(TS(p | q)); +accept_pat!(NS { f: p | q }); +accept_pat!([p | q]); + +// Non-macro tests: + +#[cfg(FALSE)] +fn or_patterns() { + // Top level of `let`: + let | A | B; + let A | B; + let A | B: u8; + let A | B = 0; + let A | B: u8 = 0; + + // Top level of `for`: + for | A | B in 0 {} + for A | B in 0 {} + + // Top level of `while`: + while let | A | B = 0 {} + while let A | B = 0 {} + + // Top level of `if`: + if let | A | B = 0 {} + if let A | B = 0 {} + + // Top level of `match` arms: + match 0 { + | A | B => {}, + A | B => {}, + } + + // Functions: + fn fun((A | B): _) {} + + // Lambdas: + let _ = |(A | B): u8| (); + + // Parenthesis and tuple patterns: + let (A | B); + let (A | B,); + + // Tuple struct patterns: + let A(B | C); + let E::V(B | C); + + // Struct patterns: + let S { f1: B | C, f2 }; + let E::V { f1: B | C, f2 }; + + // Slice patterns: + let [A | B, .. | ..]; + + // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`: + let box 0 | 1; // Unstable; we *can* the precedence if we want. + let &0 | 1; + let &mut 0 | 1; + let x @ 0 | 1; + let ref x @ 0 | 1; + let ref mut x @ 0 | 1; +} diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr new file mode 100644 index 00000000000..3145a2e9f2a --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr @@ -0,0 +1,8 @@ +warning: the feature `or_patterns` is incomplete and may cause the compiler to crash + --> $DIR/or-patterns-syntactic-pass.rs:6:12 + | +LL | #![feature(or_patterns)] + | ^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default +