diff --git a/tests/ui/parser/anon-enums.rs b/tests/ui/parser/anon-enums.rs new file mode 100644 index 0000000000000..ea70ad356f36c --- /dev/null +++ b/tests/ui/parser/anon-enums.rs @@ -0,0 +1,22 @@ +// Output of proposed syntax for anonymous enums from https://github.com/rust-lang/rfcs/issues/294. +// https://github.com/rust-lang/rust/issues/100741 + +fn foo(x: bool | i32) -> i32 | f64 { + //~^ ERROR: function parameters require top-level or-patterns in parentheses + //~| ERROR: expected one of `:`, `@`, or `|`, found `)` + //~| ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `|` + //~| ERROR: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `|` + match x { + x: i32 => x, + true => 42., + false => 0.333, + } +} + +fn main() { + match foo(true) { + 42: i32 => (), + _: f64 => (), + x: i32 => (), + } +} diff --git a/tests/ui/parser/anon-enums.stderr b/tests/ui/parser/anon-enums.stderr new file mode 100644 index 0000000000000..3124596808dc8 --- /dev/null +++ b/tests/ui/parser/anon-enums.stderr @@ -0,0 +1,28 @@ +error: function parameters require top-level or-patterns in parentheses + --> $DIR/anon-enums.rs:4:16 + | +LL | fn foo(x: bool | i32) -> i32 | f64 { + | ^^^^^ + +error: expected one of `:`, `@`, or `|`, found `)` + --> $DIR/anon-enums.rs:4:21 + | +LL | fn foo(x: bool | i32) -> i32 | f64 { + | ^ expected one of `:`, `@`, or `|` + +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `|` + --> $DIR/anon-enums.rs:4:16 + | +LL | fn foo(x: bool | i32) -> i32 | f64 { + | -^ expected one of 7 possible tokens + | | + | help: missing `,` + +error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `|` + --> $DIR/anon-enums.rs:4:30 + | +LL | fn foo(x: bool | i32) -> i32 | f64 { + | ^ expected one of 7 possible tokens + +error: aborting due to 4 previous errors + diff --git a/tests/ui/parser/fake-anon-enums-in-expressions.rs b/tests/ui/parser/fake-anon-enums-in-expressions.rs new file mode 100644 index 0000000000000..26b98c2933732 --- /dev/null +++ b/tests/ui/parser/fake-anon-enums-in-expressions.rs @@ -0,0 +1,22 @@ +//@ build-pass +// Regression test for https://github.com/rust-lang/rust/issues/107461, where anon enum syntax +// proposed in https://github.com/rust-lang/rfcs/issues/294 being parsed in a naïve way fails with +// exisitng valid syntax for closures. + +struct A; +struct B; + +#[derive(Debug)] +#[allow(unused)] +struct MyStruct { + x: f32, +} + +fn main() { + let x = |_: fn() -> A | B; + let B = x(|| A); + + let y = 1.0; + let closure = |f: fn(&f32) -> f32| MyStruct { x: f(&y) }; + println!("foo: {:?}", closure(|x| *x + 3.0)); +} diff --git a/tests/ui/parser/fake-anon-enums-in-macros.rs b/tests/ui/parser/fake-anon-enums-in-macros.rs new file mode 100644 index 0000000000000..d4086226a2e69 --- /dev/null +++ b/tests/ui/parser/fake-anon-enums-in-macros.rs @@ -0,0 +1,23 @@ +//@ build-pass +// If we ever introduce anonymous enums (https://github.com/rust-lang/rfcs/issues/294) we need to +// ensure that we don't break existing macros that expect types with `|` between them. + +macro_rules! check_ty { + ($Z:ty) => { compile_error!("triggered"); }; + ($X:ty | $Y:ty) => { $X }; +} + +macro_rules! check { + ($Z:ty) => { compile_error!("triggered"); }; + ($X:ty | $Y:ty) => { }; +} + +check! { i32 | u8 } + +fn foo(x: check_ty! { i32 | u8 }) -> check_ty! { i32 | u8 } { + x +} +fn main() { + let x: check_ty! { i32 | u8 } = 42; + let _: check_ty! { i32 | u8 } = foo(x); +}