or-patterns: add syntactic tests.

This commit is contained in:
Mazdak Farrokhzad 2019-08-18 23:53:08 +02:00
parent a9af18bed5
commit f35432e188
4 changed files with 217 additions and 0 deletions

View File

@ -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 `|`
}

View File

@ -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`.

View File

@ -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;
}

View File

@ -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