diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /tests/ui/parser/recover | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/parser/recover')
62 files changed, 2233 insertions, 0 deletions
diff --git a/tests/ui/parser/recover/binding-name-starting-with-number.rs b/tests/ui/parser/recover/binding-name-starting-with-number.rs new file mode 100644 index 000000000..6b279c553 --- /dev/null +++ b/tests/ui/parser/recover/binding-name-starting-with-number.rs @@ -0,0 +1,21 @@ +fn 1234test() { +//~^ ERROR expected identifier, found `1234test` + if let 123 = 123 { println!("yes"); } + + if let 2e1 = 123 { + //~^ ERROR mismatched types + } + + let 23name = 123; + //~^ ERROR expected identifier, found `23name` +} +fn foo() { + let 2x: i32 = 123; + //~^ ERROR expected identifier, found `2x` +} +fn bar() { + let 1x = 123; + //~^ ERROR expected identifier, found `1x` +} + +fn main() {} diff --git a/tests/ui/parser/recover/binding-name-starting-with-number.stderr b/tests/ui/parser/recover/binding-name-starting-with-number.stderr new file mode 100644 index 000000000..de59a7de0 --- /dev/null +++ b/tests/ui/parser/recover/binding-name-starting-with-number.stderr @@ -0,0 +1,59 @@ +error: expected identifier, found `1234test` + --> $DIR/binding-name-starting-with-number.rs:1:4 + | +LL | fn 1234test() { + | ^^^^^^^^ expected identifier + | +help: identifiers cannot start with a number + --> $DIR/binding-name-starting-with-number.rs:1:4 + | +LL | fn 1234test() { + | ^^^^ + +error: expected identifier, found `23name` + --> $DIR/binding-name-starting-with-number.rs:9:9 + | +LL | let 23name = 123; + | ^^^^^^ expected identifier + | +help: identifiers cannot start with a number + --> $DIR/binding-name-starting-with-number.rs:9:9 + | +LL | let 23name = 123; + | ^^ + +error: expected identifier, found `2x` + --> $DIR/binding-name-starting-with-number.rs:13:9 + | +LL | let 2x: i32 = 123; + | ^^ expected identifier + | +help: identifiers cannot start with a number + --> $DIR/binding-name-starting-with-number.rs:13:9 + | +LL | let 2x: i32 = 123; + | ^ + +error: expected identifier, found `1x` + --> $DIR/binding-name-starting-with-number.rs:17:9 + | +LL | let 1x = 123; + | ^^ expected identifier + | +help: identifiers cannot start with a number + --> $DIR/binding-name-starting-with-number.rs:17:9 + | +LL | let 1x = 123; + | ^ + +error[E0308]: mismatched types + --> $DIR/binding-name-starting-with-number.rs:5:12 + | +LL | if let 2e1 = 123 { + | ^^^ --- this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-assoc-const-constraint.rs b/tests/ui/parser/recover/recover-assoc-const-constraint.rs new file mode 100644 index 000000000..1453e6cb5 --- /dev/null +++ b/tests/ui/parser/recover/recover-assoc-const-constraint.rs @@ -0,0 +1,9 @@ +#[cfg(FALSE)] +fn syntax() { + bar::<Item = 42>(); + //~^ ERROR associated const equality is incomplete + bar::<Item = { 42 }>(); + //~^ ERROR associated const equality is incomplete +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-assoc-const-constraint.stderr b/tests/ui/parser/recover/recover-assoc-const-constraint.stderr new file mode 100644 index 000000000..2d36ce4e9 --- /dev/null +++ b/tests/ui/parser/recover/recover-assoc-const-constraint.stderr @@ -0,0 +1,21 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/recover-assoc-const-constraint.rs:3:11 + | +LL | bar::<Item = 42>(); + | ^^^^^^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error[E0658]: associated const equality is incomplete + --> $DIR/recover-assoc-const-constraint.rs:5:11 + | +LL | bar::<Item = { 42 }>(); + | ^^^^^^^^^^^^^ + | + = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/recover/recover-assoc-eq-missing-term.rs b/tests/ui/parser/recover/recover-assoc-eq-missing-term.rs new file mode 100644 index 000000000..4b42c44dc --- /dev/null +++ b/tests/ui/parser/recover/recover-assoc-eq-missing-term.rs @@ -0,0 +1,6 @@ +#[cfg(FALSE)] +fn syntax() { + bar::<Item = >(); //~ ERROR missing type to the right of `=` +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr b/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr new file mode 100644 index 000000000..cf50c0266 --- /dev/null +++ b/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr @@ -0,0 +1,18 @@ +error: missing type to the right of `=` + --> $DIR/recover-assoc-eq-missing-term.rs:3:17 + | +LL | bar::<Item = >(); + | ^^^ + | +help: to constrain the associated type, add a type after `=` + | +LL | bar::<Item = TheType>(); + | +++++++ +help: remove the `=` if `Item` is a type + | +LL - bar::<Item = >(); +LL + bar::<Item >(); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs new file mode 100644 index 000000000..558fcdfe1 --- /dev/null +++ b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs @@ -0,0 +1,6 @@ +#[cfg(FALSE)] +fn syntax() { + bar::<Item = 'a>(); //~ ERROR associated lifetimes are not supported +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr new file mode 100644 index 000000000..39a6682fc --- /dev/null +++ b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr @@ -0,0 +1,12 @@ +error: associated lifetimes are not supported + --> $DIR/recover-assoc-lifetime-constraint.rs:3:11 + | +LL | bar::<Item = 'a>(); + | ^^^^^^^-- + | | + | the lifetime is given here + | + = help: if you meant to specify a trait object, write `dyn Trait + 'lifetime` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/recover-const-async-fn-ptr.rs b/tests/ui/parser/recover/recover-const-async-fn-ptr.rs new file mode 100644 index 000000000..25af8772c --- /dev/null +++ b/tests/ui/parser/recover/recover-const-async-fn-ptr.rs @@ -0,0 +1,25 @@ +// edition:2018 + +type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const` +type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const` +type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const` +type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async` +type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async` +type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async` +type T6 = const async unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `const` +//~| ERROR an `fn` pointer type cannot be `async` + +type FT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const` +type FT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const` +type FT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const` +type FT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async` +type FT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async` +type FT5 = for<'a> async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async` +type FT6 = for<'a> const async unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `const` +//~| ERROR an `fn` pointer type cannot be `async` + +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr b/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr new file mode 100644 index 000000000..7012096b6 --- /dev/null +++ b/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr @@ -0,0 +1,155 @@ +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:3:11 + | +LL | type T0 = const fn(); + | -----^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:4:11 + | +LL | type T1 = const extern "C" fn(); + | -----^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:5:11 + | +LL | type T2 = const unsafe extern fn(); + | -----^^^^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:6:11 + | +LL | type T3 = async fn(); + | -----^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:7:11 + | +LL | type T4 = async extern fn(); + | -----^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:8:11 + | +LL | type T5 = async unsafe extern "C" fn(); + | -----^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:9:11 + | +LL | type T6 = const async unsafe extern "C" fn(); + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:9:11 + | +LL | type T6 = const async unsafe extern "C" fn(); + | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:13:12 + | +LL | type FT0 = for<'a> const fn(); + | ^^^^^^^^-----^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:14:12 + | +LL | type FT1 = for<'a> const extern "C" fn(); + | ^^^^^^^^-----^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:15:12 + | +LL | type FT2 = for<'a> const unsafe extern fn(); + | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:16:12 + | +LL | type FT3 = for<'a> async fn(); + | ^^^^^^^^-----^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:17:12 + | +LL | type FT4 = for<'a> async extern fn(); + | ^^^^^^^^-----^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:18:12 + | +LL | type FT5 = for<'a> async unsafe extern "C" fn(); + | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/recover-const-async-fn-ptr.rs:19:12 + | +LL | type FT6 = for<'a> const async unsafe extern "C" fn(); + | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/recover-const-async-fn-ptr.rs:19:12 + | +LL | type FT6 = for<'a> const async unsafe extern "C" fn(); + | ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error[E0308]: mismatched types + --> $DIR/recover-const-async-fn-ptr.rs:24:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 17 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-enum.rs b/tests/ui/parser/recover/recover-enum.rs new file mode 100644 index 000000000..08dd939e2 --- /dev/null +++ b/tests/ui/parser/recover/recover-enum.rs @@ -0,0 +1,11 @@ +fn main() { + enum Test { + Very //~ HELP missing `,` + Bad(usize) //~ HELP missing `,` + //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad` + Stuff { a: usize } //~ HELP missing `,` + //~^ ERROR expected one of `,`, `=`, or `}`, found `Stuff` + Here + //~^ ERROR expected one of `,`, `=`, or `}`, found `Here` + } +} diff --git a/tests/ui/parser/recover/recover-enum.stderr b/tests/ui/parser/recover/recover-enum.stderr new file mode 100644 index 000000000..a2b650e4f --- /dev/null +++ b/tests/ui/parser/recover/recover-enum.stderr @@ -0,0 +1,37 @@ +error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad` + --> $DIR/recover-enum.rs:4:9 + | +LL | Very + | - + | | + | expected one of `(`, `,`, `=`, `{`, or `}` + | help: missing `,` +LL | Bad(usize) + | ^^^ unexpected token + +error: expected one of `,`, `=`, or `}`, found `Stuff` + --> $DIR/recover-enum.rs:6:9 + | +LL | Bad(usize) + | - + | | + | expected one of `,`, `=`, or `}` + | help: missing `,` +LL | +LL | Stuff { a: usize } + | ^^^^^ unexpected token + +error: expected one of `,`, `=`, or `}`, found `Here` + --> $DIR/recover-enum.rs:8:9 + | +LL | Stuff { a: usize } + | - + | | + | expected one of `,`, `=`, or `}` + | help: missing `,` +LL | +LL | Here + | ^^^^ unexpected token + +error: aborting due to 3 previous errors + diff --git a/tests/ui/parser/recover/recover-enum2.rs b/tests/ui/parser/recover/recover-enum2.rs new file mode 100644 index 000000000..56b57f625 --- /dev/null +++ b/tests/ui/parser/recover/recover-enum2.rs @@ -0,0 +1,29 @@ +fn main() { + enum Test { + Var1, + Var2(String), + Var3 { + abc: {}, //~ ERROR: expected type, found `{` + }, + } + + // recover... + let () = 1; //~ ERROR mismatched types + enum Test2 { + Fine, + } + + enum Test3 { + StillFine { + def: i32, + }, + } + + { + // fail again + enum Test4 { + Nope(i32 {}) //~ ERROR: found `{` + } + let () = 1; //~ ERROR mismatched types + } +} diff --git a/tests/ui/parser/recover/recover-enum2.stderr b/tests/ui/parser/recover/recover-enum2.stderr new file mode 100644 index 000000000..132f84cc7 --- /dev/null +++ b/tests/ui/parser/recover/recover-enum2.stderr @@ -0,0 +1,37 @@ +error: expected type, found `{` + --> $DIR/recover-enum2.rs:6:18 + | +LL | Var3 { + | ---- while parsing this struct +LL | abc: {}, + | ^ expected type + +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{` + --> $DIR/recover-enum2.rs:25:22 + | +LL | enum Test4 { + | ----- while parsing this enum +LL | Nope(i32 {}) + | ^ expected one of 7 possible tokens + | + = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error[E0308]: mismatched types + --> $DIR/recover-enum2.rs:11:9 + | +LL | let () = 1; + | ^^ - this expression has type `{integer}` + | | + | expected integer, found `()` + +error[E0308]: mismatched types + --> $DIR/recover-enum2.rs:27:13 + | +LL | let () = 1; + | ^^ - this expression has type `{integer}` + | | + | expected integer, found `()` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-field-extra-angle-brackets-in-struct-with-a-field.rs b/tests/ui/parser/recover/recover-field-extra-angle-brackets-in-struct-with-a-field.rs new file mode 100644 index 000000000..e815c7611 --- /dev/null +++ b/tests/ui/parser/recover/recover-field-extra-angle-brackets-in-struct-with-a-field.rs @@ -0,0 +1,6 @@ +struct TypedArenaChunk { + next: Option<String>> + //~^ ERROR unmatched angle bracket +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr b/tests/ui/parser/recover/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr new file mode 100644 index 000000000..2b56498c5 --- /dev/null +++ b/tests/ui/parser/recover/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr @@ -0,0 +1,11 @@ +error: unmatched angle bracket + --> $DIR/recover-field-extra-angle-brackets-in-struct-with-a-field.rs:2:25 + | +LL | next: Option<String>> + | _________________________^ +LL | | +LL | | } + | |_ help: remove extra angle bracket + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/recover-field-extra-angle-brackets.rs b/tests/ui/parser/recover/recover-field-extra-angle-brackets.rs new file mode 100644 index 000000000..5e0e00bcb --- /dev/null +++ b/tests/ui/parser/recover/recover-field-extra-angle-brackets.rs @@ -0,0 +1,14 @@ +// Tests that we recover from extra trailing angle brackets +// in a struct field + +struct BadStruct { + first: Vec<u8>>, //~ ERROR unmatched angle bracket + second: bool +} + +fn bar(val: BadStruct) { + val.first; + val.second; +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-field-extra-angle-brackets.stderr b/tests/ui/parser/recover/recover-field-extra-angle-brackets.stderr new file mode 100644 index 000000000..628626926 --- /dev/null +++ b/tests/ui/parser/recover/recover-field-extra-angle-brackets.stderr @@ -0,0 +1,8 @@ +error: unmatched angle bracket + --> $DIR/recover-field-extra-angle-brackets.rs:5:19 + | +LL | first: Vec<u8>>, + | ^ help: remove extra angle bracket + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/recover-field-semi.rs b/tests/ui/parser/recover/recover-field-semi.rs new file mode 100644 index 000000000..b70357886 --- /dev/null +++ b/tests/ui/parser/recover/recover-field-semi.rs @@ -0,0 +1,16 @@ +struct Foo { + foo: i32; + //~^ ERROR struct fields are separated by `,` +} + +union Bar { //~ ERROR + foo: i32; + //~^ ERROR union fields are separated by `,` +} + +enum Baz { + Qux { foo: i32; } + //~^ ERROR struct fields are separated by `,` +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-field-semi.stderr b/tests/ui/parser/recover/recover-field-semi.stderr new file mode 100644 index 000000000..3cf484748 --- /dev/null +++ b/tests/ui/parser/recover/recover-field-semi.stderr @@ -0,0 +1,35 @@ +error: struct fields are separated by `,` + --> $DIR/recover-field-semi.rs:2:13 + | +LL | struct Foo { + | --- while parsing this struct +LL | foo: i32; + | ^ help: replace `;` with `,` + +error: union fields are separated by `,` + --> $DIR/recover-field-semi.rs:7:13 + | +LL | union Bar { + | --- while parsing this union +LL | foo: i32; + | ^ help: replace `;` with `,` + +error: struct fields are separated by `,` + --> $DIR/recover-field-semi.rs:12:19 + | +LL | Qux { foo: i32; } + | --- ^ help: replace `;` with `,` + | | + | while parsing this struct + +error: unions cannot have zero fields + --> $DIR/recover-field-semi.rs:6:1 + | +LL | / union Bar { +LL | | foo: i32; +LL | | +LL | | } + | |_^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs new file mode 100644 index 000000000..31de418be --- /dev/null +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs @@ -0,0 +1,31 @@ +fn main() { + type Predicate = fn<'a>(&'a str) -> bool; + //~^ ERROR function pointer types may not have generic parameters + + type Identity = fn<T>(T) -> T; + //~^ ERROR function pointer types may not have generic parameters + //~| ERROR cannot find type `T` in this scope + //~| ERROR cannot find type `T` in this scope + + let _: fn<const N: usize, 'e, Q, 'f>(); + //~^ ERROR function pointer types may not have generic parameters + + let _: for<'outer> fn<'inner>(); + //~^ ERROR function pointer types may not have generic parameters + + let _: for<> fn<'r>(); + //~^ ERROR function pointer types may not have generic parameters + + type Hmm = fn<>(); + //~^ ERROR function pointer types may not have generic parameters + + let _: extern fn<'a: 'static>(); + //~^ ERROR function pointer types may not have generic parameters + //~| ERROR lifetime bounds cannot be used in this context + + let _: for<'any> extern "C" fn<'u>(); + //~^ ERROR function pointer types may not have generic parameters + + type QuiteBroken = fn<const>(); + //~^ ERROR expected identifier, found `>` +} diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr new file mode 100644 index 000000000..069fcffe9 --- /dev/null +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr @@ -0,0 +1,111 @@ +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:2:24 + | +LL | type Predicate = fn<'a>(&'a str) -> bool; + | ^^^^ + | +help: consider moving the lifetime parameter to a `for` parameter list + | +LL - type Predicate = fn<'a>(&'a str) -> bool; +LL + type Predicate = for<'a> fn(&'a str) -> bool; + | + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:5:23 + | +LL | type Identity = fn<T>(T) -> T; + | ^^^ + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:10:14 + | +LL | let _: fn<const N: usize, 'e, Q, 'f>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider moving the lifetime parameters to a `for` parameter list + | +LL - let _: fn<const N: usize, 'e, Q, 'f>(); +LL + let _: for<'e, 'f> fn(); + | + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:13:26 + | +LL | let _: for<'outer> fn<'inner>(); + | ^^^^^^^^ + | +help: consider moving the lifetime parameter to the `for` parameter list + | +LL - let _: for<'outer> fn<'inner>(); +LL + let _: for<'outer, 'inner> fn(); + | + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:16:20 + | +LL | let _: for<> fn<'r>(); + | ^^^^ + | +help: consider moving the lifetime parameter to the `for` parameter list + | +LL - let _: for<> fn<'r>(); +LL + let _: for<'r> fn(); + | + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:19:18 + | +LL | type Hmm = fn<>(); + | ^^ + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:22:21 + | +LL | let _: extern fn<'a: 'static>(); + | ^^^^^^^^^^^^^ + | +help: consider moving the lifetime parameter to a `for` parameter list + | +LL - let _: extern fn<'a: 'static>(); +LL + let _: for<'a> extern fn(); + | + +error: function pointer types may not have generic parameters + --> $DIR/recover-fn-ptr-with-generics.rs:26:35 + | +LL | let _: for<'any> extern "C" fn<'u>(); + | ^^^^ + | +help: consider moving the lifetime parameter to the `for` parameter list + | +LL - let _: for<'any> extern "C" fn<'u>(); +LL + let _: for<'any, 'u> extern "C" fn(); + | + +error: expected identifier, found `>` + --> $DIR/recover-fn-ptr-with-generics.rs:29:32 + | +LL | type QuiteBroken = fn<const>(); + | ^ expected identifier + +error[E0412]: cannot find type `T` in this scope + --> $DIR/recover-fn-ptr-with-generics.rs:5:27 + | +LL | type Identity = fn<T>(T) -> T; + | ^ not found in this scope + +error[E0412]: cannot find type `T` in this scope + --> $DIR/recover-fn-ptr-with-generics.rs:5:33 + | +LL | type Identity = fn<T>(T) -> T; + | ^ not found in this scope + +error: lifetime bounds cannot be used in this context + --> $DIR/recover-fn-ptr-with-generics.rs:22:26 + | +LL | let _: extern fn<'a: 'static>(); + | ^^^^^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.rs b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.rs new file mode 100644 index 000000000..b6611e627 --- /dev/null +++ b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.rs @@ -0,0 +1,12 @@ +fn foo(_: impl fn() -> i32) {} +//~^ ERROR expected identifier, found keyword `fn` + +fn foo2<T: fn(i32)>(_: T) {} +//~^ ERROR expected identifier, found keyword `fn` + +fn main() { + foo(|| ()); + //~^ mismatched types + foo2(|_: ()| {}); + //~^ type mismatch in closure arguments +} diff --git a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr new file mode 100644 index 000000000..3681a796c --- /dev/null +++ b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr @@ -0,0 +1,48 @@ +error: expected identifier, found keyword `fn` + --> $DIR/recover-fn-trait-from-fn-kw.rs:1:16 + | +LL | fn foo(_: impl fn() -> i32) {} + | ^^ + | +help: use `Fn` to refer to the trait + | +LL | fn foo(_: impl Fn() -> i32) {} + | ~~ + +error: expected identifier, found keyword `fn` + --> $DIR/recover-fn-trait-from-fn-kw.rs:4:12 + | +LL | fn foo2<T: fn(i32)>(_: T) {} + | ^^ + | +help: use `Fn` to refer to the trait + | +LL | fn foo2<T: Fn(i32)>(_: T) {} + | ~~ + +error[E0308]: mismatched types + --> $DIR/recover-fn-trait-from-fn-kw.rs:8:12 + | +LL | foo(|| ()); + | ^^ expected `i32`, found `()` + +error[E0631]: type mismatch in closure arguments + --> $DIR/recover-fn-trait-from-fn-kw.rs:10:5 + | +LL | foo2(|_: ()| {}); + | ^^^^ ------- found signature defined here + | | + | expected due to this + | + = note: expected closure signature `fn(i32) -> _` + found closure signature `fn(()) -> _` +note: required by a bound in `foo2` + --> $DIR/recover-fn-trait-from-fn-kw.rs:4:12 + | +LL | fn foo2<T: fn(i32)>(_: T) {} + | ^^^^^^^ required by this bound in `foo2` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0308, E0631. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-for-loop-parens-around-head.fixed b/tests/ui/parser/recover/recover-for-loop-parens-around-head.fixed new file mode 100644 index 000000000..6afc2d993 --- /dev/null +++ b/tests/ui/parser/recover/recover-for-loop-parens-around-head.fixed @@ -0,0 +1,15 @@ +// run-rustfix +// Here we test that the parser is able to recover in a situation like +// `for ( $pat in $expr )` since that is familiar syntax in other languages. +// Instead we suggest that the user writes `for $pat in $expr`. + +#![deny(unused)] // Make sure we don't trigger `unused_parens`. + +fn main() { + let vec = vec![1, 2, 3]; + + for _elem in vec { + //~^ ERROR unexpected parentheses surrounding `for` loop head + const _RECOVERY_WITNESS: u32 = 0u32; //~ ERROR mismatched types + } +} diff --git a/tests/ui/parser/recover/recover-for-loop-parens-around-head.rs b/tests/ui/parser/recover/recover-for-loop-parens-around-head.rs new file mode 100644 index 000000000..b1716900c --- /dev/null +++ b/tests/ui/parser/recover/recover-for-loop-parens-around-head.rs @@ -0,0 +1,15 @@ +// run-rustfix +// Here we test that the parser is able to recover in a situation like +// `for ( $pat in $expr )` since that is familiar syntax in other languages. +// Instead we suggest that the user writes `for $pat in $expr`. + +#![deny(unused)] // Make sure we don't trigger `unused_parens`. + +fn main() { + let vec = vec![1, 2, 3]; + + for ( _elem in vec ) { + //~^ ERROR unexpected parentheses surrounding `for` loop head + const _RECOVERY_WITNESS: u32 = 0u8; //~ ERROR mismatched types + } +} diff --git a/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr b/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr new file mode 100644 index 000000000..beaa346e7 --- /dev/null +++ b/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr @@ -0,0 +1,26 @@ +error: unexpected parentheses surrounding `for` loop head + --> $DIR/recover-for-loop-parens-around-head.rs:11:9 + | +LL | for ( _elem in vec ) { + | ^ ^ + | +help: remove parentheses in `for` loop + | +LL - for ( _elem in vec ) { +LL + for _elem in vec { + | + +error[E0308]: mismatched types + --> $DIR/recover-for-loop-parens-around-head.rs:13:40 + | +LL | const _RECOVERY_WITNESS: u32 = 0u8; + | ^^^ expected `u32`, found `u8` + | +help: change the type of the numeric literal from `u8` to `u32` + | +LL | const _RECOVERY_WITNESS: u32 = 0u32; + | ~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-from-bad-variant.rs b/tests/ui/parser/recover/recover-from-bad-variant.rs new file mode 100644 index 000000000..e8887147c --- /dev/null +++ b/tests/ui/parser/recover/recover-from-bad-variant.rs @@ -0,0 +1,15 @@ +enum Enum { + Foo { a: usize, b: usize }, + Bar(usize, usize), +} + +fn main() { + let x = Enum::Foo(a: 3, b: 4); + //~^ ERROR invalid `struct` delimiters or `fn` call arguments + match x { + Enum::Foo(a, b) => {} + //~^ ERROR expected tuple struct or tuple variant, found struct variant `Enum::Foo` + Enum::Bar { a, b } => {} + //~^ ERROR tuple variant `Enum::Bar` written as struct variant + } +} diff --git a/tests/ui/parser/recover/recover-from-bad-variant.stderr b/tests/ui/parser/recover/recover-from-bad-variant.stderr new file mode 100644 index 000000000..04968bbdf --- /dev/null +++ b/tests/ui/parser/recover/recover-from-bad-variant.stderr @@ -0,0 +1,37 @@ +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/recover-from-bad-variant.rs:7:13 + | +LL | let x = Enum::Foo(a: 3, b: 4); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: if `Enum::Foo` is a struct, use braces as delimiters + | +LL | let x = Enum::Foo { a: 3, b: 4 }; + | ~ ~ +help: if `Enum::Foo` is a function, use the arguments directly + | +LL - let x = Enum::Foo(a: 3, b: 4); +LL + let x = Enum::Foo(3, 4); + | + +error[E0164]: expected tuple struct or tuple variant, found struct variant `Enum::Foo` + --> $DIR/recover-from-bad-variant.rs:10:9 + | +LL | Enum::Foo(a, b) => {} + | ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant + +error[E0769]: tuple variant `Enum::Bar` written as struct variant + --> $DIR/recover-from-bad-variant.rs:12:9 + | +LL | Enum::Bar { a, b } => {} + | ^^^^^^^^^^^^^^^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL | Enum::Bar(a, b) => {} + | ~~~~~~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0164, E0769. +For more information about an error, try `rustc --explain E0164`. diff --git a/tests/ui/parser/recover/recover-from-homoglyph.rs b/tests/ui/parser/recover/recover-from-homoglyph.rs new file mode 100644 index 000000000..99ce0d1a6 --- /dev/null +++ b/tests/ui/parser/recover/recover-from-homoglyph.rs @@ -0,0 +1,4 @@ +fn main() { + println!(""); //~ ERROR unknown start of token: \u{37e} + let x: usize = (); //~ ERROR mismatched types +} diff --git a/tests/ui/parser/recover/recover-from-homoglyph.stderr b/tests/ui/parser/recover/recover-from-homoglyph.stderr new file mode 100644 index 000000000..f11ca9fd5 --- /dev/null +++ b/tests/ui/parser/recover/recover-from-homoglyph.stderr @@ -0,0 +1,22 @@ +error: unknown start of token: \u{37e} + --> $DIR/recover-from-homoglyph.rs:2:17 + | +LL | println!(""); + | ^ + | +help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not + | +LL | println!(""); + | ~ + +error[E0308]: mismatched types + --> $DIR/recover-from-homoglyph.rs:3:20 + | +LL | let x: usize = (); + | ----- ^^ expected `usize`, found `()` + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-labeled-non-block-expr.fixed b/tests/ui/parser/recover/recover-labeled-non-block-expr.fixed new file mode 100644 index 000000000..c2e76444d --- /dev/null +++ b/tests/ui/parser/recover/recover-labeled-non-block-expr.fixed @@ -0,0 +1,26 @@ +// run-rustfix +fn main() { + let _ = 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + + match () { () => {}, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + 'label: { match () { () => break 'label, } }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + #[allow(unused_labels)] + 'label: { match () { () => 'lp: loop { break 'lp 0 }, } }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + + let x = 1; + let _i = 'label: { match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label + 0 => 42, + 1 if false => break 'label 17, + 1 => { + if true { + break 'label 13 + } else { + break 'label 0; + } + } + _ => 1, + } }; + + let other = 3; + let _val = 'label: { (1, if other == 3 { break 'label (2, 3) } else { other }) }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label +} diff --git a/tests/ui/parser/recover/recover-labeled-non-block-expr.rs b/tests/ui/parser/recover/recover-labeled-non-block-expr.rs new file mode 100644 index 000000000..fc11c646a --- /dev/null +++ b/tests/ui/parser/recover/recover-labeled-non-block-expr.rs @@ -0,0 +1,26 @@ +// run-rustfix +fn main() { + let _ = 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + + 'label: match () { () => {}, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + 'label: match () { () => break 'label, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + #[allow(unused_labels)] + 'label: match () { () => 'lp: loop { break 'lp 0 }, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + + let x = 1; + let _i = 'label: match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label + 0 => 42, + 1 if false => break 'label 17, + 1 => { + if true { + break 'label 13 + } else { + break 'label 0; + } + } + _ => 1, + }; + + let other = 3; + let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); //~ ERROR expected `while`, `for`, `loop` or `{` after a label +} diff --git a/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr b/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr new file mode 100644 index 000000000..d66ce6950 --- /dev/null +++ b/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr @@ -0,0 +1,74 @@ +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:3:21 + | +LL | let _ = 'label: 1 + 1; + | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - let _ = 'label: 1 + 1; +LL + let _ = 1 + 1; + | + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:5:13 + | +LL | 'label: match () { () => {}, }; + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - 'label: match () { () => {}, }; +LL + match () { () => {}, }; + | + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:6:13 + | +LL | 'label: match () { () => break 'label, }; + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL | 'label: { match () { () => break 'label, } }; + | + + + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:8:13 + | +LL | 'label: match () { () => 'lp: loop { break 'lp 0 }, }; + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL | 'label: { match () { () => 'lp: loop { break 'lp 0 }, } }; + | + + + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:11:22 + | +LL | let _i = 'label: match x { + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL ~ let _i = 'label: { match x { +LL | 0 => 42, + ... +LL | _ => 1, +LL ~ } }; + | + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:25:24 + | +LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); + | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL | let _val = 'label: { (1, if other == 3 { break 'label (2, 3) } else { other }) }; + | + + + +error: aborting due to 6 previous errors + diff --git a/tests/ui/parser/recover/recover-missing-semi-before-item.fixed b/tests/ui/parser/recover/recover-missing-semi-before-item.fixed new file mode 100644 index 000000000..acb846373 --- /dev/null +++ b/tests/ui/parser/recover/recover-missing-semi-before-item.fixed @@ -0,0 +1,61 @@ +// run-rustfix + +#![allow(unused_variables, dead_code, unused_imports)] + +fn for_struct() { + let foo = 3; //~ ERROR expected `;`, found keyword `struct` + struct Foo; +} + +fn for_union() { + let foo = 3; //~ ERROR expected `;`, found `union` + union Foo { + foo: usize, + } +} + +fn for_enum() { + let foo = 3; //~ ERROR expected `;`, found keyword `enum` + enum Foo { + Bar, + } +} + +fn for_fn() { + let foo = 3; //~ ERROR expected `;`, found keyword `fn` + fn foo() {} +} + +fn for_extern() { + let foo = 3; //~ ERROR expected `;`, found keyword `extern` + extern fn foo() {} +} + +fn for_impl() { + struct Foo; + let foo = 3; //~ ERROR expected `;`, found keyword `impl` + impl Foo {} +} + +fn for_use() { + let foo = 3; //~ ERROR expected `;`, found keyword `pub` + pub use bar::Bar; +} + +fn for_mod() { + let foo = 3; //~ ERROR expected `;`, found keyword `mod` + mod foo {} +} + +fn for_type() { + let foo = 3; //~ ERROR expected `;`, found keyword `type` + type Foo = usize; +} + +mod bar { + pub struct Bar; +} + +const X: i32 = 123; //~ ERROR expected `;`, found keyword `fn` + +fn main() {} diff --git a/tests/ui/parser/recover/recover-missing-semi-before-item.rs b/tests/ui/parser/recover/recover-missing-semi-before-item.rs new file mode 100644 index 000000000..ef6cfe3c4 --- /dev/null +++ b/tests/ui/parser/recover/recover-missing-semi-before-item.rs @@ -0,0 +1,61 @@ +// run-rustfix + +#![allow(unused_variables, dead_code, unused_imports)] + +fn for_struct() { + let foo = 3 //~ ERROR expected `;`, found keyword `struct` + struct Foo; +} + +fn for_union() { + let foo = 3 //~ ERROR expected `;`, found `union` + union Foo { + foo: usize, + } +} + +fn for_enum() { + let foo = 3 //~ ERROR expected `;`, found keyword `enum` + enum Foo { + Bar, + } +} + +fn for_fn() { + let foo = 3 //~ ERROR expected `;`, found keyword `fn` + fn foo() {} +} + +fn for_extern() { + let foo = 3 //~ ERROR expected `;`, found keyword `extern` + extern fn foo() {} +} + +fn for_impl() { + struct Foo; + let foo = 3 //~ ERROR expected `;`, found keyword `impl` + impl Foo {} +} + +fn for_use() { + let foo = 3 //~ ERROR expected `;`, found keyword `pub` + pub use bar::Bar; +} + +fn for_mod() { + let foo = 3 //~ ERROR expected `;`, found keyword `mod` + mod foo {} +} + +fn for_type() { + let foo = 3 //~ ERROR expected `;`, found keyword `type` + type Foo = usize; +} + +mod bar { + pub struct Bar; +} + +const X: i32 = 123 //~ ERROR expected `;`, found keyword `fn` + +fn main() {} diff --git a/tests/ui/parser/recover/recover-missing-semi-before-item.stderr b/tests/ui/parser/recover/recover-missing-semi-before-item.stderr new file mode 100644 index 000000000..61c43f2f1 --- /dev/null +++ b/tests/ui/parser/recover/recover-missing-semi-before-item.stderr @@ -0,0 +1,83 @@ +error: expected `;`, found keyword `struct` + --> $DIR/recover-missing-semi-before-item.rs:6:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | struct Foo; + | ------ unexpected token + +error: expected `;`, found `union` + --> $DIR/recover-missing-semi-before-item.rs:11:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | union Foo { + | ----- unexpected token + +error: expected `;`, found keyword `enum` + --> $DIR/recover-missing-semi-before-item.rs:18:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | enum Foo { + | ---- unexpected token + +error: expected `;`, found keyword `fn` + --> $DIR/recover-missing-semi-before-item.rs:25:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | fn foo() {} + | -- unexpected token + +error: expected `;`, found keyword `extern` + --> $DIR/recover-missing-semi-before-item.rs:30:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | extern fn foo() {} + | ------ unexpected token + +error: expected `;`, found keyword `impl` + --> $DIR/recover-missing-semi-before-item.rs:36:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | impl Foo {} + | ---- unexpected token + +error: expected `;`, found keyword `pub` + --> $DIR/recover-missing-semi-before-item.rs:41:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | pub use bar::Bar; + | --- unexpected token + +error: expected `;`, found keyword `mod` + --> $DIR/recover-missing-semi-before-item.rs:46:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | mod foo {} + | --- unexpected token + +error: expected `;`, found keyword `type` + --> $DIR/recover-missing-semi-before-item.rs:51:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | type Foo = usize; + | ---- unexpected token + +error: expected `;`, found keyword `fn` + --> $DIR/recover-missing-semi-before-item.rs:59:19 + | +LL | const X: i32 = 123 + | ^ help: add `;` here +LL | +LL | fn main() {} + | -- unexpected token + +error: aborting due to 10 previous errors + diff --git a/tests/ui/parser/recover/recover-missing-semi.rs b/tests/ui/parser/recover/recover-missing-semi.rs new file mode 100644 index 000000000..f47d5e680 --- /dev/null +++ b/tests/ui/parser/recover/recover-missing-semi.rs @@ -0,0 +1,13 @@ +fn main() { + let _: usize = () + //~^ ERROR mismatched types + //~| ERROR expected `;` + let _ = 3; +} + +fn foo() -> usize { + let _: usize = () + //~^ ERROR mismatched types + //~| ERROR expected `;` + return 3; +} diff --git a/tests/ui/parser/recover/recover-missing-semi.stderr b/tests/ui/parser/recover/recover-missing-semi.stderr new file mode 100644 index 000000000..ba4798285 --- /dev/null +++ b/tests/ui/parser/recover/recover-missing-semi.stderr @@ -0,0 +1,37 @@ +error: expected `;`, found keyword `let` + --> $DIR/recover-missing-semi.rs:2:22 + | +LL | let _: usize = () + | ^ help: add `;` here +... +LL | let _ = 3; + | --- unexpected token + +error: expected `;`, found keyword `return` + --> $DIR/recover-missing-semi.rs:9:22 + | +LL | let _: usize = () + | ^ help: add `;` here +... +LL | return 3; + | ------ unexpected token + +error[E0308]: mismatched types + --> $DIR/recover-missing-semi.rs:2:20 + | +LL | let _: usize = () + | ----- ^^ expected `usize`, found `()` + | | + | expected due to this + +error[E0308]: mismatched types + --> $DIR/recover-missing-semi.rs:9:20 + | +LL | let _: usize = () + | ----- ^^ expected `usize`, found `()` + | | + | expected due to this + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-parens-around-match-arm-head.fixed b/tests/ui/parser/recover/recover-parens-around-match-arm-head.fixed new file mode 100644 index 000000000..6b9b7fa88 --- /dev/null +++ b/tests/ui/parser/recover/recover-parens-around-match-arm-head.fixed @@ -0,0 +1,12 @@ +// run-rustfix +fn main() { + let val = 42; + let x = match val { + 0 if true => { + //~^ ERROR unexpected parentheses surrounding `match` arm pattern + 42u8 + } + _ => 0u8, + }; + let _y: u32 = x.into(); //~ ERROR mismatched types +} diff --git a/tests/ui/parser/recover/recover-parens-around-match-arm-head.rs b/tests/ui/parser/recover/recover-parens-around-match-arm-head.rs new file mode 100644 index 000000000..f523581e2 --- /dev/null +++ b/tests/ui/parser/recover/recover-parens-around-match-arm-head.rs @@ -0,0 +1,12 @@ +// run-rustfix +fn main() { + let val = 42; + let x = match val { + (0 if true) => { + //~^ ERROR unexpected parentheses surrounding `match` arm pattern + 42u8 + } + _ => 0u8, + }; + let _y: u32 = x; //~ ERROR mismatched types +} diff --git a/tests/ui/parser/recover/recover-parens-around-match-arm-head.stderr b/tests/ui/parser/recover/recover-parens-around-match-arm-head.stderr new file mode 100644 index 000000000..bad4d7d2f --- /dev/null +++ b/tests/ui/parser/recover/recover-parens-around-match-arm-head.stderr @@ -0,0 +1,28 @@ +error: unexpected parentheses surrounding `match` arm pattern + --> $DIR/recover-parens-around-match-arm-head.rs:5:9 + | +LL | (0 if true) => { + | ^ ^ + | +help: remove parentheses surrounding the pattern + | +LL - (0 if true) => { +LL + 0 if true => { + | + +error[E0308]: mismatched types + --> $DIR/recover-parens-around-match-arm-head.rs:11:19 + | +LL | let _y: u32 = x; + | --- ^ expected `u32`, found `u8` + | | + | expected due to this + | +help: you can convert a `u8` to a `u32` + | +LL | let _y: u32 = x.into(); + | +++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-quantified-closure.rs b/tests/ui/parser/recover/recover-quantified-closure.rs new file mode 100644 index 000000000..10af39b70 --- /dev/null +++ b/tests/ui/parser/recover/recover-quantified-closure.rs @@ -0,0 +1,12 @@ +fn main() { + for<'a> |x: &'a u8| *x + 1; + //~^ ERROR `for<...>` binders for closures are experimental + //~^^ ERROR implicit types in closure signatures are forbidden when `for<...>` is present +} + +enum Foo { Bar } +fn foo(x: impl Iterator<Item = Foo>) { + for <Foo>::Bar in x {} + //~^ ERROR expected one of `move`, `static`, `|` + //~^^ ERROR `for<...>` binders for closures are experimental +} diff --git a/tests/ui/parser/recover/recover-quantified-closure.stderr b/tests/ui/parser/recover/recover-quantified-closure.stderr new file mode 100644 index 000000000..37e93cbee --- /dev/null +++ b/tests/ui/parser/recover/recover-quantified-closure.stderr @@ -0,0 +1,37 @@ +error: expected one of `move`, `static`, `|`, or `||`, found `::` + --> $DIR/recover-quantified-closure.rs:9:14 + | +LL | for <Foo>::Bar in x {} + | ^^ expected one of `move`, `static`, `|`, or `||` + +error[E0658]: `for<...>` binders for closures are experimental + --> $DIR/recover-quantified-closure.rs:2:5 + | +LL | for<'a> |x: &'a u8| *x + 1; + | ^^^^^^^ + | + = note: see issue #97362 <https://github.com/rust-lang/rust/issues/97362> for more information + = help: add `#![feature(closure_lifetime_binder)]` to the crate attributes to enable + = help: consider removing `for<...>` + +error[E0658]: `for<...>` binders for closures are experimental + --> $DIR/recover-quantified-closure.rs:9:5 + | +LL | for <Foo>::Bar in x {} + | ^^^^^^^^^ + | + = note: see issue #97362 <https://github.com/rust-lang/rust/issues/97362> for more information + = help: add `#![feature(closure_lifetime_binder)]` to the crate attributes to enable + = help: consider removing `for<...>` + +error: implicit types in closure signatures are forbidden when `for<...>` is present + --> $DIR/recover-quantified-closure.rs:2:24 + | +LL | for<'a> |x: &'a u8| *x + 1; + | ------- ^ + | | + | `for<...>` is here + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/recover/recover-range-pats.rs b/tests/ui/parser/recover/recover-range-pats.rs new file mode 100644 index 000000000..156c7ad94 --- /dev/null +++ b/tests/ui/parser/recover/recover-range-pats.rs @@ -0,0 +1,159 @@ +// Here we test all kinds of range patterns in terms of parsing / recovery. +// We want to ensure that: +// 1. Things parse as they should. +// 2. Or at least we have parser recovery if they don't. + +#![feature(exclusive_range_pattern)] +#![deny(ellipsis_inclusive_range_patterns)] + +fn main() {} + +const X: u8 = 0; +const Y: u8 = 3; + +fn exclusive_from_to() { + if let 0..3 = 0 {} // OK. + if let 0..Y = 0 {} // OK. + if let X..3 = 0 {} // OK. + if let X..Y = 0 {} // OK. + if let true..Y = 0 {} //~ ERROR only `char` and numeric types + if let X..true = 0 {} //~ ERROR only `char` and numeric types + if let .0..Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + if let X.. .0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part +} + +fn inclusive_from_to() { + if let 0..=3 = 0 {} // OK. + if let 0..=Y = 0 {} // OK. + if let X..=3 = 0 {} // OK. + if let X..=Y = 0 {} // OK. + if let true..=Y = 0 {} //~ ERROR only `char` and numeric types + if let X..=true = 0 {} //~ ERROR only `char` and numeric types + if let .0..=Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + if let X..=.0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part +} + +fn inclusive2_from_to() { + if let 0...3 = 0 {} + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + if let 0...Y = 0 {} + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + if let X...3 = 0 {} + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + if let X...Y = 0 {} + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + if let true...Y = 0 {} //~ ERROR only `char` and numeric types + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + if let X...true = 0 {} //~ ERROR only `char` and numeric types + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + if let .0...Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + //~| WARN this is accepted in the current edition + //~| ERROR `...` range patterns are deprecated + if let X... .0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition +} + +fn exclusive_from() { + if let 0.. = 0 {} + if let X.. = 0 {} + if let true.. = 0 {} + //~^ ERROR only `char` and numeric types + if let .0.. = 0 {} + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive_from() { + if let 0..= = 0 {} //~ ERROR inclusive range with no end + if let X..= = 0 {} //~ ERROR inclusive range with no end + if let true..= = 0 {} //~ ERROR inclusive range with no end + //~| ERROR only `char` and numeric types + if let .0..= = 0 {} //~ ERROR inclusive range with no end + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive2_from() { + if let 0... = 0 {} //~ ERROR inclusive range with no end + if let X... = 0 {} //~ ERROR inclusive range with no end + if let true... = 0 {} //~ ERROR inclusive range with no end + //~| ERROR only `char` and numeric types + if let .0... = 0 {} //~ ERROR inclusive range with no end + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn exclusive_to() { + if let ..0 = 0 {} + if let ..Y = 0 {} + if let ..true = 0 {} + //~^ ERROR only `char` and numeric types + if let .. .0 = 0 {} + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive_to() { + if let ..=3 = 0 {} + if let ..=Y = 0 {} + if let ..=true = 0 {} + //~^ ERROR only `char` and numeric types + if let ..=.0 = 0 {} + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive2_to() { + if let ...3 = 0 {} + //~^ ERROR range-to patterns with `...` are not allowed + if let ...Y = 0 {} + //~^ ERROR range-to patterns with `...` are not allowed + if let ...true = 0 {} + //~^ ERROR range-to patterns with `...` are not allowed + //~| ERROR only `char` and numeric types + if let ....3 = 0 {} + //~^ ERROR float literals must have an integer part + //~| ERROR range-to patterns with `...` are not allowed + //~| ERROR mismatched types +} + +fn with_macro_expr_var() { + macro_rules! mac2 { + ($e1:expr, $e2:expr) => { + let $e1..$e2; + let $e1...$e2; + //~^ ERROR `...` range patterns are deprecated + //~| WARN this is accepted in the current edition + let $e1..=$e2; + } + } + + mac2!(0, 1); + + macro_rules! mac { + ($e:expr) => { + let ..$e; + let ...$e; + //~^ ERROR range-to patterns with `...` are not allowed + let ..=$e; + let $e..; + let $e...; //~ ERROR inclusive range with no end + let $e..=; //~ ERROR inclusive range with no end + } + } + + mac!(0); +} diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr new file mode 100644 index 000000000..5b69ca5cd --- /dev/null +++ b/tests/ui/parser/recover/recover-range-pats.stderr @@ -0,0 +1,484 @@ +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:21:12 + | +LL | if let .0..Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:23:16 + | +LL | if let X.. .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:34:12 + | +LL | if let .0..=Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:36:16 + | +LL | if let X..=.0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:59:12 + | +LL | if let .0...Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:63:17 + | +LL | if let X... .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:74:12 + | +LL | if let .0.. = 0 {} + | ^^ help: must have an integer part: `0.0` + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:80:13 + | +LL | if let 0..= = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:81:13 + | +LL | if let X..= = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:82:16 + | +LL | if let true..= = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:84:12 + | +LL | if let .0..= = 0 {} + | ^^ help: must have an integer part: `0.0` + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:84:14 + | +LL | if let .0..= = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:90:13 + | +LL | if let 0... = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:91:13 + | +LL | if let X... = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:92:16 + | +LL | if let true... = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:94:12 + | +LL | if let .0... = 0 {} + | ^^ help: must have an integer part: `0.0` + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:94:14 + | +LL | if let .0... = 0 {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:104:15 + | +LL | if let .. .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:114:15 + | +LL | if let ..=.0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:120:12 + | +LL | if let ...3 = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:122:12 + | +LL | if let ...Y = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:124:12 + | +LL | if let ...true = 0 {} + | ^^^ help: use `..=` instead + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:127:15 + | +LL | if let ....3 = 0 {} + | ^^ help: must have an integer part: `0.3` + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:127:12 + | +LL | if let ....3 = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:149:17 + | +LL | let ...$e; + | ^^^ help: use `..=` instead +... +LL | mac!(0); + | ------- in this macro invocation + | + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:153:19 + | +LL | let $e...; + | ^^^ help: use `..` instead +... +LL | mac!(0); + | ------- in this macro invocation + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:154:19 + | +LL | let $e..=; + | ^^^ help: use `..` instead +... +LL | mac!(0); + | ------- in this macro invocation + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:41:13 + | +LL | if let 0...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +note: the lint level is defined here + --> $DIR/recover-range-pats.rs:7:9 + | +LL | #![deny(ellipsis_inclusive_range_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:44:13 + | +LL | if let 0...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:47:13 + | +LL | if let X...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:50:13 + | +LL | if let X...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:53:16 + | +LL | if let true...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:56:13 + | +LL | if let X...true = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:59:14 + | +LL | if let .0...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:63:13 + | +LL | if let X... .0 = 0 {} + | ^^^ help: use `..=` for an inclusive range + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:137:20 + | +LL | let $e1...$e2; + | ^^^ help: use `..=` for an inclusive range +... +LL | mac2!(0, 1); + | ----------- in this macro invocation + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:19:12 + | +LL | if let true..Y = 0 {} + | ^^^^ - this is of type `u8` + | | + | this is of type `bool` but it should be `char` or numeric + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:20:15 + | +LL | if let X..true = 0 {} + | - ^^^^ this is of type `bool` but it should be `char` or numeric + | | + | this is of type `u8` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:21:12 + | +LL | if let .0..Y = 0 {} + | ^^ - - this expression has type `{integer}` + | | | + | | this is of type `u8` + | expected integer, found floating-point number + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:23:16 + | +LL | if let X.. .0 = 0 {} + | - ^^ - this expression has type `u8` + | | | + | | expected `u8`, found floating-point number + | this is of type `u8` + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:32:12 + | +LL | if let true..=Y = 0 {} + | ^^^^ - this is of type `u8` + | | + | this is of type `bool` but it should be `char` or numeric + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:33:16 + | +LL | if let X..=true = 0 {} + | - ^^^^ this is of type `bool` but it should be `char` or numeric + | | + | this is of type `u8` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:34:12 + | +LL | if let .0..=Y = 0 {} + | ^^ - - this expression has type `{integer}` + | | | + | | this is of type `u8` + | expected integer, found floating-point number + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:36:16 + | +LL | if let X..=.0 = 0 {} + | - ^^ - this expression has type `u8` + | | | + | | expected `u8`, found floating-point number + | this is of type `u8` + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:53:12 + | +LL | if let true...Y = 0 {} + | ^^^^ - this is of type `u8` + | | + | this is of type `bool` but it should be `char` or numeric + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:56:16 + | +LL | if let X...true = 0 {} + | - ^^^^ this is of type `bool` but it should be `char` or numeric + | | + | this is of type `u8` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:59:12 + | +LL | if let .0...Y = 0 {} + | ^^ - - this expression has type `{integer}` + | | | + | | this is of type `u8` + | expected integer, found floating-point number + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:63:17 + | +LL | if let X... .0 = 0 {} + | - ^^ - this expression has type `u8` + | | | + | | expected `u8`, found floating-point number + | this is of type `u8` + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:72:12 + | +LL | if let true.. = 0 {} + | ^^^^ this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:74:12 + | +LL | if let .0.. = 0 {} + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:82:12 + | +LL | if let true..= = 0 {} + | ^^^^ this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:84:12 + | +LL | if let .0..= = 0 {} + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:92:12 + | +LL | if let true... = 0 {} + | ^^^^ this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:94:12 + | +LL | if let .0... = 0 {} + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:102:14 + | +LL | if let ..true = 0 {} + | ^^^^ this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:104:15 + | +LL | if let .. .0 = 0 {} + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:112:15 + | +LL | if let ..=true = 0 {} + | ^^^^ this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:114:15 + | +LL | if let ..=.0 = 0 {} + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:124:15 + | +LL | if let ...true = 0 {} + | ^^^^ this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:127:15 + | +LL | if let ....3 = 0 {} + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number + +error: aborting due to 60 previous errors + +Some errors have detailed explanations: E0029, E0308, E0586. +For more information about an error, try `rustc --explain E0029`. diff --git a/tests/ui/parser/recover/recover-ref-dyn-mut.rs b/tests/ui/parser/recover/recover-ref-dyn-mut.rs new file mode 100644 index 000000000..3016275cc --- /dev/null +++ b/tests/ui/parser/recover/recover-ref-dyn-mut.rs @@ -0,0 +1,9 @@ +// Test that the parser detects `&dyn mut`, offers a help message, and +// recovers. + +fn main() { + let r: &dyn mut Trait; + //~^ ERROR: `mut` must precede `dyn` + //~| HELP: place `mut` before `dyn` + //~| ERROR: cannot find trait `Trait` in this scope [E0405] +} diff --git a/tests/ui/parser/recover/recover-ref-dyn-mut.stderr b/tests/ui/parser/recover/recover-ref-dyn-mut.stderr new file mode 100644 index 000000000..c048c8ea1 --- /dev/null +++ b/tests/ui/parser/recover/recover-ref-dyn-mut.stderr @@ -0,0 +1,15 @@ +error: `mut` must precede `dyn` + --> $DIR/recover-ref-dyn-mut.rs:5:12 + | +LL | let r: &dyn mut Trait; + | ^^^^^^^^ help: place `mut` before `dyn`: `&mut dyn` + +error[E0405]: cannot find trait `Trait` in this scope + --> $DIR/recover-ref-dyn-mut.rs:5:21 + | +LL | let r: &dyn mut Trait; + | ^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/parser/recover/recover-struct.rs b/tests/ui/parser/recover/recover-struct.rs new file mode 100644 index 000000000..bfa5b454c --- /dev/null +++ b/tests/ui/parser/recover/recover-struct.rs @@ -0,0 +1,7 @@ +fn main() { + struct Test { + Very + Bad //~ ERROR found `Bad` + Stuff + } +} diff --git a/tests/ui/parser/recover/recover-struct.stderr b/tests/ui/parser/recover/recover-struct.stderr new file mode 100644 index 000000000..51a9e7077 --- /dev/null +++ b/tests/ui/parser/recover/recover-struct.stderr @@ -0,0 +1,12 @@ +error: expected `:`, found `Bad` + --> $DIR/recover-struct.rs:4:9 + | +LL | struct Test { + | ---- while parsing this struct +LL | Very + | - expected `:` +LL | Bad + | ^^^ unexpected token + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/recover-tuple-pat.rs b/tests/ui/parser/recover/recover-tuple-pat.rs new file mode 100644 index 000000000..7fded752d --- /dev/null +++ b/tests/ui/parser/recover/recover-tuple-pat.rs @@ -0,0 +1,12 @@ +// NOTE: This doesn't recover anymore. + +fn main() { + let x = (1, 2, 3, 4); + match x { + (1, .., 4) => {} + (1, .=., 4) => { let _: usize = ""; } + //~^ ERROR expected pattern, found `.` + (.=., 4) => {} + (1, 2, 3, 4) => {} + } +} diff --git a/tests/ui/parser/recover/recover-tuple-pat.stderr b/tests/ui/parser/recover/recover-tuple-pat.stderr new file mode 100644 index 000000000..e181f0720 --- /dev/null +++ b/tests/ui/parser/recover/recover-tuple-pat.stderr @@ -0,0 +1,8 @@ +error: expected pattern, found `.` + --> $DIR/recover-tuple-pat.rs:7:13 + | +LL | (1, .=., 4) => { let _: usize = ""; } + | ^ expected pattern + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/recover-tuple.rs b/tests/ui/parser/recover/recover-tuple.rs new file mode 100644 index 000000000..59e2695de --- /dev/null +++ b/tests/ui/parser/recover/recover-tuple.rs @@ -0,0 +1,11 @@ +fn main() { + // no complaints about the tuple not matching the expected type + let x: (usize, usize, usize) = (3, .=.); + //~^ ERROR expected expression, found `.` + // verify that the parser recovers: + let y: usize = ""; //~ ERROR mismatched types + // no complaints about the type + foo(x); +} + +fn foo(_: (usize, usize, usize)) {} diff --git a/tests/ui/parser/recover/recover-tuple.stderr b/tests/ui/parser/recover/recover-tuple.stderr new file mode 100644 index 000000000..88891b54b --- /dev/null +++ b/tests/ui/parser/recover/recover-tuple.stderr @@ -0,0 +1,17 @@ +error: expected expression, found `.` + --> $DIR/recover-tuple.rs:3:40 + | +LL | let x: (usize, usize, usize) = (3, .=.); + | ^ expected expression + +error[E0308]: mismatched types + --> $DIR/recover-tuple.rs:6:20 + | +LL | let y: usize = ""; + | ----- ^^ expected `usize`, found `&str` + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/recover/recover-unticked-labels.fixed b/tests/ui/parser/recover/recover-unticked-labels.fixed new file mode 100644 index 000000000..159d995b8 --- /dev/null +++ b/tests/ui/parser/recover/recover-unticked-labels.fixed @@ -0,0 +1,7 @@ +// run-rustfix + +fn main() { + 'label: loop { break 'label }; //~ error: cannot find value `label` in this scope + 'label: loop { break 'label 0 }; //~ error: expected a label, found an identifier + 'label: loop { continue 'label }; //~ error: expected a label, found an identifier +} diff --git a/tests/ui/parser/recover/recover-unticked-labels.rs b/tests/ui/parser/recover/recover-unticked-labels.rs new file mode 100644 index 000000000..56034de68 --- /dev/null +++ b/tests/ui/parser/recover/recover-unticked-labels.rs @@ -0,0 +1,7 @@ +// run-rustfix + +fn main() { + 'label: loop { break label }; //~ error: cannot find value `label` in this scope + 'label: loop { break label 0 }; //~ error: expected a label, found an identifier + 'label: loop { continue label }; //~ error: expected a label, found an identifier +} diff --git a/tests/ui/parser/recover/recover-unticked-labels.stderr b/tests/ui/parser/recover/recover-unticked-labels.stderr new file mode 100644 index 000000000..fbd108ca6 --- /dev/null +++ b/tests/ui/parser/recover/recover-unticked-labels.stderr @@ -0,0 +1,29 @@ +error: expected a label, found an identifier + --> $DIR/recover-unticked-labels.rs:5:26 + | +LL | 'label: loop { break label 0 }; + | -^^^^ + | | + | help: labels start with a tick + +error: expected a label, found an identifier + --> $DIR/recover-unticked-labels.rs:6:29 + | +LL | 'label: loop { continue label }; + | -^^^^ + | | + | help: labels start with a tick + +error[E0425]: cannot find value `label` in this scope + --> $DIR/recover-unticked-labels.rs:4:26 + | +LL | 'label: loop { break label }; + | ------ ^^^^^ + | | | + | | not found in this scope + | | help: use the similarly named label: `'label` + | a label with a similar name exists + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed new file mode 100644 index 000000000..227c40e97 --- /dev/null +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed @@ -0,0 +1,15 @@ +// Regression test for issues #100790 and #106439. +// run-rustfix + +pub struct Example(usize) +where + (): Sized; +//~^^^ ERROR where clauses are not allowed before tuple struct bodies + +struct _Demo(pub usize, usize) +where + (): Sized, + String: Clone; +//~^^^^ ERROR where clauses are not allowed before tuple struct bodies + +fn main() {} diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs new file mode 100644 index 000000000..3699e6fe5 --- /dev/null +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs @@ -0,0 +1,17 @@ +// Regression test for issues #100790 and #106439. +// run-rustfix + +pub struct Example +where + (): Sized, +(usize); +//~^^^ ERROR where clauses are not allowed before tuple struct bodies + +struct _Demo +where + (): Sized, + String: Clone, +(pub usize, usize); +//~^^^^ ERROR where clauses are not allowed before tuple struct bodies + +fn main() {} diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr new file mode 100644 index 000000000..18aa5fadb --- /dev/null +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr @@ -0,0 +1,40 @@ +error: where clauses are not allowed before tuple struct bodies + --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:5:1 + | +LL | pub struct Example + | ------- while parsing this tuple struct +LL | / where +LL | | (): Sized, + | |______________^ unexpected where clause +LL | (usize); + | ------- the struct body + | +help: move the body before the where clause + | +LL ~ pub struct Example(usize) +LL | where +LL ~ (): Sized; + | + +error: where clauses are not allowed before tuple struct bodies + --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:11:1 + | +LL | struct _Demo + | ----- while parsing this tuple struct +LL | / where +LL | | (): Sized, +LL | | String: Clone, + | |__________________^ unexpected where clause +LL | (pub usize, usize); + | ------------------ the struct body + | +help: move the body before the where clause + | +LL ~ struct _Demo(pub usize, usize) +LL | where +LL | (): Sized, +LL ~ String: Clone; + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-1.rs b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-1.rs new file mode 100644 index 000000000..f515ae81e --- /dev/null +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-1.rs @@ -0,0 +1,7 @@ +// Regression test for issues #100790 and #106439. + +// Make sure that we still show a helpful error message even if the trailing semicolon is missing. + +struct Foo<T> where T: MyTrait, (T) +//~^ ERROR where clauses are not allowed before tuple struct bodies +//~| ERROR expected `;`, found `<eof>` diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-1.stderr b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-1.stderr new file mode 100644 index 000000000..2219c2a73 --- /dev/null +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-1.stderr @@ -0,0 +1,23 @@ +error: where clauses are not allowed before tuple struct bodies + --> $DIR/recover-where-clause-before-tuple-struct-body-1.rs:5:15 + | +LL | struct Foo<T> where T: MyTrait, (T) + | --- ^^^^^^^^^^^^^^^^^ --- the struct body + | | | + | | unexpected where clause + | while parsing this tuple struct + | +help: move the body before the where clause + | +LL - struct Foo<T> where T: MyTrait, (T) +LL + struct Foo<T>(T) where T: MyTrait + | + +error: expected `;`, found `<eof>` + --> $DIR/recover-where-clause-before-tuple-struct-body-1.rs:5:35 + | +LL | struct Foo<T> where T: MyTrait, (T) + | ^ expected `;` + +error: aborting due to 2 previous errors + |