diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/parser | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
1138 files changed, 23500 insertions, 0 deletions
diff --git a/src/test/ui/parser/ascii-only-character-escape.rs b/src/test/ui/parser/ascii-only-character-escape.rs new file mode 100644 index 000000000..725c8ad23 --- /dev/null +++ b/src/test/ui/parser/ascii-only-character-escape.rs @@ -0,0 +1,6 @@ +fn main() { + let x = "\x80"; //~ ERROR out of range hex escape + let y = "\xff"; //~ ERROR out of range hex escape + let z = "\xe2"; //~ ERROR out of range hex escape + let a = b"\x00e2"; // ok because byte literal +} diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr new file mode 100644 index 000000000..b599b35f4 --- /dev/null +++ b/src/test/ui/parser/ascii-only-character-escape.stderr @@ -0,0 +1,20 @@ +error: out of range hex escape + --> $DIR/ascii-only-character-escape.rs:2:14 + | +LL | let x = "\x80"; + | ^^^^ must be a character in the range [\x00-\x7f] + +error: out of range hex escape + --> $DIR/ascii-only-character-escape.rs:3:14 + | +LL | let y = "\xff"; + | ^^^^ must be a character in the range [\x00-\x7f] + +error: out of range hex escape + --> $DIR/ascii-only-character-escape.rs:4:14 + | +LL | let z = "\xe2"; + | ^^^^ must be a character in the range [\x00-\x7f] + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/assoc-const-underscore-semantic-fail.rs b/src/test/ui/parser/assoc-const-underscore-semantic-fail.rs new file mode 100644 index 000000000..d37ce06c5 --- /dev/null +++ b/src/test/ui/parser/assoc-const-underscore-semantic-fail.rs @@ -0,0 +1,17 @@ +// Semantically, an associated constant cannot use `_` as a name. + +fn main() {} + +const _: () = { + pub trait A { + const _: () = (); //~ ERROR `const` items in this context need a name + } + impl A for () { + const _: () = (); //~ ERROR `const` items in this context need a name + //~^ ERROR const `_` is not a member of trait `A` + } + struct B; + impl B { + const _: () = (); //~ ERROR `const` items in this context need a name + } +}; diff --git a/src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr b/src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr new file mode 100644 index 000000000..538bf0ec1 --- /dev/null +++ b/src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr @@ -0,0 +1,27 @@ +error: `const` items in this context need a name + --> $DIR/assoc-const-underscore-semantic-fail.rs:7:15 + | +LL | const _: () = (); + | ^ `_` is not a valid name for this `const` item + +error: `const` items in this context need a name + --> $DIR/assoc-const-underscore-semantic-fail.rs:10:15 + | +LL | const _: () = (); + | ^ `_` is not a valid name for this `const` item + +error: `const` items in this context need a name + --> $DIR/assoc-const-underscore-semantic-fail.rs:15:15 + | +LL | const _: () = (); + | ^ `_` is not a valid name for this `const` item + +error[E0438]: const `_` is not a member of trait `A` + --> $DIR/assoc-const-underscore-semantic-fail.rs:10:9 + | +LL | const _: () = (); + | ^^^^^^^^^^^^^^^^^ not a member of trait `A` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0438`. diff --git a/src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs b/src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs new file mode 100644 index 000000000..60da408c8 --- /dev/null +++ b/src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs @@ -0,0 +1,18 @@ +// All constant items (associated or otherwise) may syntactically use `_` as a name. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +const _: () = { + pub trait A { + const _: () = (); + } + impl A for () { + const _: () = (); + } + impl dyn A { + const _: () = (); + } +}; diff --git a/src/test/ui/parser/assoc-oddities-1.rs b/src/test/ui/parser/assoc-oddities-1.rs new file mode 100644 index 000000000..5914805e5 --- /dev/null +++ b/src/test/ui/parser/assoc-oddities-1.rs @@ -0,0 +1,11 @@ +// compile-flags: -Z parse-only + +fn main() { + // following lines below parse and must not fail + x = if c { a } else { b }(); + x = if true { 1 } else { 0 } as *mut _; + // however this does not parse and probably should fail to retain compat? + // N.B., `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=` + // see assoc-oddities-2 and assoc-oddities-3 + ..if c { a } else { b }[n]; //~ ERROR expected one of +} diff --git a/src/test/ui/parser/assoc-oddities-1.stderr b/src/test/ui/parser/assoc-oddities-1.stderr new file mode 100644 index 000000000..acf71b489 --- /dev/null +++ b/src/test/ui/parser/assoc-oddities-1.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `;`, `?`, or `}`, found `[` + --> $DIR/assoc-oddities-1.rs:10:28 + | +LL | ..if c { a } else { b }[n]; + | ^ expected one of `.`, `;`, `?`, or `}` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/assoc-oddities-2.rs b/src/test/ui/parser/assoc-oddities-2.rs new file mode 100644 index 000000000..3d35aad74 --- /dev/null +++ b/src/test/ui/parser/assoc-oddities-2.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z parse-only + +fn main() { + // see assoc-oddities-1 for explanation + x..if c { a } else { b }[n]; //~ ERROR expected one of +} diff --git a/src/test/ui/parser/assoc-oddities-2.stderr b/src/test/ui/parser/assoc-oddities-2.stderr new file mode 100644 index 000000000..d3b90c34c --- /dev/null +++ b/src/test/ui/parser/assoc-oddities-2.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `;`, `?`, or `}`, found `[` + --> $DIR/assoc-oddities-2.rs:5:29 + | +LL | x..if c { a } else { b }[n]; + | ^ expected one of `.`, `;`, `?`, or `}` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/assoc-static-semantic-fail.rs b/src/test/ui/parser/assoc-static-semantic-fail.rs new file mode 100644 index 000000000..a8759d209 --- /dev/null +++ b/src/test/ui/parser/assoc-static-semantic-fail.rs @@ -0,0 +1,52 @@ +// Semantically, we do not allow e.g., `static X: u8 = 0;` as an associated item. + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +fn main() {} + +struct S; +impl S { + static IA: u8 = 0; + //~^ ERROR associated `static` items are not allowed + static IB: u8; + //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body + default static IC: u8 = 0; + //~^ ERROR associated `static` items are not allowed + //~| ERROR a static item cannot be `default` + pub(crate) default static ID: u8; + //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body + //~| ERROR a static item cannot be `default` +} + +trait T { + static TA: u8 = 0; + //~^ ERROR associated `static` items are not allowed + static TB: u8; + //~^ ERROR associated `static` items are not allowed + default static TC: u8 = 0; + //~^ ERROR associated `static` items are not allowed + //~| ERROR a static item cannot be `default` + pub(crate) default static TD: u8; + //~^ ERROR associated `static` items are not allowed + //~| ERROR unnecessary visibility qualifier + //~| ERROR a static item cannot be `default` +} + +impl T for S { + static TA: u8 = 0; + //~^ ERROR associated `static` items are not allowed + static TB: u8; + //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body + default static TC: u8 = 0; + //~^ ERROR associated `static` items are not allowed + //~| ERROR a static item cannot be `default` + pub default static TD: u8; + //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body + //~| ERROR unnecessary visibility qualifier + //~| ERROR a static item cannot be `default` +} diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr new file mode 100644 index 000000000..7ae092cee --- /dev/null +++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr @@ -0,0 +1,177 @@ +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:10:5 + | +LL | static IA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:12:5 + | +LL | static IB: u8; + | ^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:15:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:15:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:18:16 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:18:5 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:25:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:27:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:29:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:29:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:32:16 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:32:5 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:39:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:41:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:44:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:44:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:47:9 + | +LL | pub default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:47:5 + | +LL | pub default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:12:5 + | +LL | static IB: u8; + | ^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:18:5 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error[E0449]: unnecessary visibility qualifier + --> $DIR/assoc-static-semantic-fail.rs:32:5 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^ + +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:41:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:47:5 + | +LL | pub default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error[E0449]: unnecessary visibility qualifier + --> $DIR/assoc-static-semantic-fail.rs:47:5 + | +LL | pub default static TD: u8; + | ^^^ `pub` not permitted here because it's implied + +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/assoc-static-semantic-fail.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + +error: aborting due to 24 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0449`. diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.rs b/src/test/ui/parser/assoc-static-syntactic-fail.rs new file mode 100644 index 000000000..492f2ea16 --- /dev/null +++ b/src/test/ui/parser/assoc-static-syntactic-fail.rs @@ -0,0 +1,33 @@ +// Syntactically, we do allow e.g., `static X: u8 = 0;` as an associated item. + +fn main() {} + +#[cfg(FALSE)] +impl S { + static IA: u8 = 0; //~ ERROR associated `static` items are not allowed + static IB: u8; //~ ERROR associated `static` items are not allowed + default static IC: u8 = 0; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` + pub(crate) default static ID: u8; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` +} + +#[cfg(FALSE)] +trait T { + static TA: u8 = 0; //~ ERROR associated `static` items are not allowed + static TB: u8; //~ ERROR associated `static` items are not allowed + default static TC: u8 = 0; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` + pub(crate) default static TD: u8; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` +} + +#[cfg(FALSE)] +impl T for S { + static TA: u8 = 0; //~ ERROR associated `static` items are not allowed + static TB: u8; //~ ERROR associated `static` items are not allowed + default static TC: u8 = 0; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` + pub default static TD: u8; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` +} diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.stderr b/src/test/ui/parser/assoc-static-syntactic-fail.stderr new file mode 100644 index 000000000..e97236145 --- /dev/null +++ b/src/test/ui/parser/assoc-static-syntactic-fail.stderr @@ -0,0 +1,122 @@ +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:7:5 + | +LL | static IA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:8:5 + | +LL | static IB: u8; + | ^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:9:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:9:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:11:16 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:11:5 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:17:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:18:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:19:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:19:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:21:16 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:21:5 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:27:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:28:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:29:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:29:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:31:9 + | +LL | pub default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:31:5 + | +LL | pub default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 18 previous errors + diff --git a/src/test/ui/parser/assoc-type-in-type-arg.rs b/src/test/ui/parser/assoc-type-in-type-arg.rs new file mode 100644 index 000000000..000956ea2 --- /dev/null +++ b/src/test/ui/parser/assoc-type-in-type-arg.rs @@ -0,0 +1,11 @@ +trait Tr { + type TrSubtype; +} + +struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> { + //~^ ERROR bounds on associated types do not belong here + item: Item, + item_sub: &'a <Item as Tr>::TrSubtype, +} + +fn main() {} diff --git a/src/test/ui/parser/assoc-type-in-type-arg.stderr b/src/test/ui/parser/assoc-type-in-type-arg.stderr new file mode 100644 index 000000000..b637702f2 --- /dev/null +++ b/src/test/ui/parser/assoc-type-in-type-arg.stderr @@ -0,0 +1,8 @@ +error: bounds on associated types do not belong here + --> $DIR/assoc-type-in-type-arg.rs:5:26 + | +LL | struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ belongs in `where` clause + +error: aborting due to previous error + diff --git a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs new file mode 100644 index 000000000..b238a9ca2 --- /dev/null +++ b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs @@ -0,0 +1,16 @@ +// Test you can't use a higher-ranked trait bound inside of a qualified +// path (just won't parse). + +pub trait Foo<T> { + type A; + + fn get(&self, t: T) -> Self::A; +} + +fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A) + //~^ ERROR expected identifier, found keyword `for` + //~| ERROR expected one of `::` or `>` +{ +} + +pub fn main() {} diff --git a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr new file mode 100644 index 000000000..aa0fa0e3c --- /dev/null +++ b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr @@ -0,0 +1,14 @@ +error: expected identifier, found keyword `for` + --> $DIR/associated-types-project-from-hrtb-explicit.rs:10:21 + | +LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A) + | ^^^ expected identifier, found keyword + +error: expected one of `::` or `>`, found `Foo` + --> $DIR/associated-types-project-from-hrtb-explicit.rs:10:29 + | +LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A) + | ^^^ expected one of `::` or `>` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/attr-bad-meta-2.rs b/src/test/ui/parser/attr-bad-meta-2.rs new file mode 100644 index 000000000..db612ed88 --- /dev/null +++ b/src/test/ui/parser/attr-bad-meta-2.rs @@ -0,0 +1,2 @@ +#[path =] //~ ERROR expected expression, found `]` +mod m {} diff --git a/src/test/ui/parser/attr-bad-meta-2.stderr b/src/test/ui/parser/attr-bad-meta-2.stderr new file mode 100644 index 000000000..6fc6fb665 --- /dev/null +++ b/src/test/ui/parser/attr-bad-meta-2.stderr @@ -0,0 +1,8 @@ +error: expected expression, found `]` + --> $DIR/attr-bad-meta-2.rs:1:9 + | +LL | #[path =] + | ^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-bad-meta-3.rs b/src/test/ui/parser/attr-bad-meta-3.rs new file mode 100644 index 000000000..b51e9f221 --- /dev/null +++ b/src/test/ui/parser/attr-bad-meta-3.rs @@ -0,0 +1,2 @@ +#[path() token] //~ ERROR expected `]`, found `token` +mod m {} diff --git a/src/test/ui/parser/attr-bad-meta-3.stderr b/src/test/ui/parser/attr-bad-meta-3.stderr new file mode 100644 index 000000000..4fa420c79 --- /dev/null +++ b/src/test/ui/parser/attr-bad-meta-3.stderr @@ -0,0 +1,8 @@ +error: expected `]`, found `token` + --> $DIR/attr-bad-meta-3.rs:1:10 + | +LL | #[path() token] + | ^^^^^ expected `]` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-bad-meta.rs b/src/test/ui/parser/attr-bad-meta.rs new file mode 100644 index 000000000..8001977f5 --- /dev/null +++ b/src/test/ui/parser/attr-bad-meta.rs @@ -0,0 +1,2 @@ +#[path*] //~ ERROR expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*` +mod m {} diff --git a/src/test/ui/parser/attr-bad-meta.stderr b/src/test/ui/parser/attr-bad-meta.stderr new file mode 100644 index 000000000..8d65c423c --- /dev/null +++ b/src/test/ui/parser/attr-bad-meta.stderr @@ -0,0 +1,8 @@ +error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*` + --> $DIR/attr-bad-meta.rs:1:7 + | +LL | #[path*] + | ^ expected one of `(`, `::`, `=`, `[`, `]`, or `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-before-eof.rs b/src/test/ui/parser/attr-before-eof.rs new file mode 100644 index 000000000..6af1783e6 --- /dev/null +++ b/src/test/ui/parser/attr-before-eof.rs @@ -0,0 +1,3 @@ +fn main() {} + +#[derive(Debug)] //~ERROR expected item after attributes diff --git a/src/test/ui/parser/attr-before-eof.stderr b/src/test/ui/parser/attr-before-eof.stderr new file mode 100644 index 000000000..a2acb9437 --- /dev/null +++ b/src/test/ui/parser/attr-before-eof.stderr @@ -0,0 +1,8 @@ +error: expected item after attributes + --> $DIR/attr-before-eof.rs:3:1 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-dangling-in-fn.rs b/src/test/ui/parser/attr-dangling-in-fn.rs new file mode 100644 index 000000000..c7c45bafb --- /dev/null +++ b/src/test/ui/parser/attr-dangling-in-fn.rs @@ -0,0 +1,8 @@ +// error-pattern:expected statement + +fn f() { + #[foo = "bar"] +} + +fn main() { +} diff --git a/src/test/ui/parser/attr-dangling-in-fn.stderr b/src/test/ui/parser/attr-dangling-in-fn.stderr new file mode 100644 index 000000000..b1bb3ab3b --- /dev/null +++ b/src/test/ui/parser/attr-dangling-in-fn.stderr @@ -0,0 +1,8 @@ +error: expected statement after outer attribute + --> $DIR/attr-dangling-in-fn.rs:4:3 + | +LL | #[foo = "bar"] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-dangling-in-mod.rs b/src/test/ui/parser/attr-dangling-in-mod.rs new file mode 100644 index 000000000..261ed3913 --- /dev/null +++ b/src/test/ui/parser/attr-dangling-in-mod.rs @@ -0,0 +1,6 @@ +// error-pattern:expected item + +fn main() { +} + +#[foo = "bar"] diff --git a/src/test/ui/parser/attr-dangling-in-mod.stderr b/src/test/ui/parser/attr-dangling-in-mod.stderr new file mode 100644 index 000000000..1c892eac0 --- /dev/null +++ b/src/test/ui/parser/attr-dangling-in-mod.stderr @@ -0,0 +1,8 @@ +error: expected item after attributes + --> $DIR/attr-dangling-in-mod.rs:6:1 + | +LL | #[foo = "bar"] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs new file mode 100644 index 000000000..09f494bdc --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs @@ -0,0 +1,111 @@ +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = [#[attr]]; } +//~^ ERROR expected expression, found `]` +#[cfg(FALSE)] fn e() { let _ = foo#[attr](); } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } +//~^ ERROR an inner attribute is not permitted in this context +//~| ERROR expected expression, found `)` +#[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } +//~^ ERROR an inner attribute is not permitted in this context +//~| ERROR expected expression, found `)` +#[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } +//~^ ERROR expected expression, found `..` +#[cfg(FALSE)] fn e() { let _ = #[attr] ..; } +//~^ ERROR expected expression, found `..` +#[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context + +#[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +//~^ ERROR an inner attribute is not permitted following an outer attribute + +// FIXME: Allow attributes in pattern constexprs? +// note: requires parens in patterns to allow disambiguation + +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } +//~^ ERROR inclusive range with no end +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } +//~^ ERROR inclusive range with no end +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } +//~^ ERROR unexpected token: `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } +//~^ ERROR inclusive range with no end +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` + +#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } +//~^ ERROR unexpected token: `#` +//~| ERROR expected one of `.` +#[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } +//~^ ERROR unexpected token: `#` +//~| ERROR expected one of `.` + +// make sure we don't catch this bug again... +#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } +//~^ ERROR expected statement after outer attribute +#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } +//~^ ERROR expected statement after outer attribute diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr new file mode 100644 index 000000000..7bb3db030 --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -0,0 +1,445 @@ +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:5:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected expression, found `]` + --> $DIR/attr-stmt-expr-attr-bad.rs:7:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = [#[attr]]; } + | ^ expected expression + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:9:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo#[attr](); } + | ^ expected one of 8 possible tokens + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:11:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected expression, found `)` + --> $DIR/attr-stmt-expr-attr-bad.rs:11:44 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } + | ^ expected expression + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:14:38 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected expression, found `)` + --> $DIR/attr-stmt-expr-attr-bad.rs:14:46 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } + | ^ expected expression + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:17:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:19:33 + | +LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:21:33 + | +LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:23:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } + | ^ expected one of 8 possible tokens + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:25:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:27:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:29:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected expression, found `..` + --> $DIR/attr-stmt-expr-attr-bad.rs:33:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } + | ^^ expected expression + +error: expected expression, found `..` + --> $DIR/attr-stmt-expr-attr-bad.rs:35:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } + | ^^ expected expression + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:37:41 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:39:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:41:37 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:43:38 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:45:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:47:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } + | ---- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:49:46 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } + | ---- ^^^^^^^ ------- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:53:50 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:55:51 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:57:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:59:46 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:61:48 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:63:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } + | ---- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:65:54 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:67:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } + | ---- ^^^^^^^ --------------- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:69:66 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:71:67 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:74:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } + | ------- ^^^^^^^^ not permitted following an outer attribute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:76:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } + | ------- ^^^^^^^^ not permitted following an outer attribute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:78:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); } + | + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:80:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; } + | + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:82:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } + | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; } + | + +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:88:35 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:88:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } + | ^ expected one of `=>`, `if`, or `|` + +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:91:35 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:91:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } + | ^ expected one of `=>`, `if`, or `|` + +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:94:39 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } + | ^ + +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:96:35 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:96:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } + | ^ expected one of `=>`, `if`, or `|` + +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } + | ^ + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:103:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } + | ^ + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:103:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: expected statement after outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:108:37 + | +LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } + | ^^^^^^^ + +error: expected statement after outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:110:37 + | +LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } + | ^^^^^^^ + +error: aborting due to 53 previous errors + +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/parser/attr-with-a-semicolon.rs b/src/test/ui/parser/attr-with-a-semicolon.rs new file mode 100644 index 000000000..56fe40b91 --- /dev/null +++ b/src/test/ui/parser/attr-with-a-semicolon.rs @@ -0,0 +1,4 @@ +#[derive(Debug, Clone)]; //~ERROR expected item after attributes +struct Foo; + +fn main() {} diff --git a/src/test/ui/parser/attr-with-a-semicolon.stderr b/src/test/ui/parser/attr-with-a-semicolon.stderr new file mode 100644 index 000000000..0de3490b8 --- /dev/null +++ b/src/test/ui/parser/attr-with-a-semicolon.stderr @@ -0,0 +1,14 @@ +error: expected item after attributes + --> $DIR/attr-with-a-semicolon.rs:1:1 + | +LL | #[derive(Debug, Clone)]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider removing this semicolon + | +LL - #[derive(Debug, Clone)]; +LL + #[derive(Debug, Clone)] + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr.rs b/src/test/ui/parser/attr.rs new file mode 100644 index 000000000..42b2dfde8 --- /dev/null +++ b/src/test/ui/parser/attr.rs @@ -0,0 +1,6 @@ +#![feature(lang_items)] + +fn main() {} + +#![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context +fn foo() {} diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr new file mode 100644 index 000000000..7cd0ac224 --- /dev/null +++ b/src/test/ui/parser/attr.stderr @@ -0,0 +1,17 @@ +error: an inner attribute is not permitted in this context + --> $DIR/attr.rs:5:1 + | +LL | #![lang = "foo"] + | ^^^^^^^^^^^^^^^^ +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![lang = "foo"] +LL + #[lang = "foo"] + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs new file mode 100644 index 000000000..c2cc91d8f --- /dev/null +++ b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs @@ -0,0 +1,3 @@ +fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters + +fn main() {} diff --git a/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr new file mode 100644 index 000000000..4c5964715 --- /dev/null +++ b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr @@ -0,0 +1,8 @@ +error: attribute without generic parameters + --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8 + | +LL | fn foo<#[attr]>() {} + | ^^^^^^^ attributes are only permitted when preceding parameters + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attrs-after-extern-mod.rs b/src/test/ui/parser/attrs-after-extern-mod.rs new file mode 100644 index 000000000..e3f0fa0fc --- /dev/null +++ b/src/test/ui/parser/attrs-after-extern-mod.rs @@ -0,0 +1,7 @@ +// Make sure there's an error when given `extern { ... #[attr] }`. + +fn main() {} + +extern "C" { + #[cfg(stage37)] //~ ERROR expected item after attributes +} diff --git a/src/test/ui/parser/attrs-after-extern-mod.stderr b/src/test/ui/parser/attrs-after-extern-mod.stderr new file mode 100644 index 000000000..135d98457 --- /dev/null +++ b/src/test/ui/parser/attrs-after-extern-mod.stderr @@ -0,0 +1,12 @@ +error: expected item after attributes + --> $DIR/attrs-after-extern-mod.rs:6:5 + | +LL | extern "C" { + | - while parsing this item list starting here +LL | #[cfg(stage37)] + | ^^^^^^^^^^^^^^^ +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-char-literals.rs b/src/test/ui/parser/bad-char-literals.rs new file mode 100644 index 000000000..748b4a222 --- /dev/null +++ b/src/test/ui/parser/bad-char-literals.rs @@ -0,0 +1,20 @@ +// ignore-tidy-cr +// ignore-tidy-tab + +fn main() { + // these literals are just silly. + '''; + //~^ ERROR: character constant must be escaped: `'` + + // note that this is a literal "\n" byte + ' +'; + //~^^ ERROR: character constant must be escaped: `\n` + + // note that this is a literal "\r" byte + '
'; //~ ERROR: character constant must be escaped: `\r` + + // note that this is a literal tab character here + ' '; + //~^ ERROR: character constant must be escaped: `\t` +} diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr new file mode 100644 index 000000000..a22ddbac1 --- /dev/null +++ b/src/test/ui/parser/bad-char-literals.stderr @@ -0,0 +1,28 @@ +error: character constant must be escaped: `'` + --> $DIR/bad-char-literals.rs:6:6 + | +LL | '''; + | ^ help: escape the character: `\'` + +error: character constant must be escaped: `\n` + --> $DIR/bad-char-literals.rs:10:6 + | +LL | ' + | ______^ +LL | | '; + | |_ help: escape the character: `\n` + +error: character constant must be escaped: `\r` + --> $DIR/bad-char-literals.rs:15:6 + | +LL | '
'; + | ^ help: escape the character: `\r` + +error: character constant must be escaped: `\t` + --> $DIR/bad-char-literals.rs:18:6 + | +LL | ' '; + | ^^^^ help: escape the character: `\t` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/bad-crate-name.rs b/src/test/ui/parser/bad-crate-name.rs new file mode 100644 index 000000000..837d5c354 --- /dev/null +++ b/src/test/ui/parser/bad-crate-name.rs @@ -0,0 +1,5 @@ +extern crate krate-name-here; +//~^ ERROR crate name using dashes are not valid in `extern crate` statements +//~| ERROR can't find crate for `krate_name_here` + +fn main() {} diff --git a/src/test/ui/parser/bad-crate-name.stderr b/src/test/ui/parser/bad-crate-name.stderr new file mode 100644 index 000000000..c98a620f1 --- /dev/null +++ b/src/test/ui/parser/bad-crate-name.stderr @@ -0,0 +1,20 @@ +error: crate name using dashes are not valid in `extern crate` statements + --> $DIR/bad-crate-name.rs:1:14 + | +LL | extern crate krate-name-here; + | ^^^^^^^^^^^^^^^ dash-separated idents are not valid + | +help: if the original crate name uses dashes you need to use underscores in the code + | +LL | extern crate krate_name_here; + | ~ ~ + +error[E0463]: can't find crate for `krate_name_here` + --> $DIR/bad-crate-name.rs:1:1 + | +LL | extern crate krate-name-here; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/parser/bad-escape-suggest-raw-string.rs b/src/test/ui/parser/bad-escape-suggest-raw-string.rs new file mode 100644 index 000000000..978b92cbc --- /dev/null +++ b/src/test/ui/parser/bad-escape-suggest-raw-string.rs @@ -0,0 +1,7 @@ +fn main() { + let ok = r"ab\[c"; + let bad = "ab\[c"; + //~^ ERROR unknown character escape: `[` + //~| HELP for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + //~| HELP if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal +} diff --git a/src/test/ui/parser/bad-escape-suggest-raw-string.stderr b/src/test/ui/parser/bad-escape-suggest-raw-string.stderr new file mode 100644 index 000000000..fc34bd328 --- /dev/null +++ b/src/test/ui/parser/bad-escape-suggest-raw-string.stderr @@ -0,0 +1,14 @@ +error: unknown character escape: `[` + --> $DIR/bad-escape-suggest-raw-string.rs:3:19 + | +LL | let bad = "ab\[c"; + | ^ unknown character escape + | + = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL | let bad = r"ab\[c"; + | ~~~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.fixed b/src/test/ui/parser/bad-fn-ptr-qualifier.fixed new file mode 100644 index 000000000..ad8e718cf --- /dev/null +++ b/src/test/ui/parser/bad-fn-ptr-qualifier.fixed @@ -0,0 +1,26 @@ +// run-rustfix +// edition:2018 +// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix. + +pub type T0 = fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type T1 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type T2 = unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type T3 = fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type T4 = extern fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type T5 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type T6 = unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `const` +//~| ERROR an `fn` pointer type cannot be `async` + +pub type FTT0 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type FTT1 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type FTT2 = for<'a> unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type FTT3 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type FTT4 = for<'a> extern fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type FTT5 = for<'a> unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `async` +pub type FTT6 = for<'a> unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `const` +//~| ERROR an `fn` pointer type cannot be `async` + +fn main() {} diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.rs b/src/test/ui/parser/bad-fn-ptr-qualifier.rs new file mode 100644 index 000000000..c04813dad --- /dev/null +++ b/src/test/ui/parser/bad-fn-ptr-qualifier.rs @@ -0,0 +1,26 @@ +// run-rustfix +// edition:2018 +// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix. + +pub type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type T6 = const async unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `const` +//~| ERROR an `fn` pointer type cannot be `async` + +pub type FTT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type FTT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type FTT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const` +pub type FTT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type FTT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async` +pub type FTT5 = for<'a> async unsafe extern "C" fn(); +//~^ ERROR an `fn` pointer type cannot be `async` +pub type FTT6 = 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() {} diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.stderr b/src/test/ui/parser/bad-fn-ptr-qualifier.stderr new file mode 100644 index 000000000..265e31329 --- /dev/null +++ b/src/test/ui/parser/bad-fn-ptr-qualifier.stderr @@ -0,0 +1,146 @@ +error: an `fn` pointer type cannot be `const` + --> $DIR/bad-fn-ptr-qualifier.rs:5:15 + | +LL | pub type T0 = const fn(); + | -----^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/bad-fn-ptr-qualifier.rs:6:15 + | +LL | pub type T1 = const extern "C" fn(); + | -----^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/bad-fn-ptr-qualifier.rs:7:15 + | +LL | pub type T2 = const unsafe extern fn(); + | -----^^^^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/bad-fn-ptr-qualifier.rs:8:15 + | +LL | pub type T3 = async fn(); + | -----^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/bad-fn-ptr-qualifier.rs:9:15 + | +LL | pub type T4 = async extern fn(); + | -----^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/bad-fn-ptr-qualifier.rs:10:15 + | +LL | pub 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/bad-fn-ptr-qualifier.rs:11:15 + | +LL | pub 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/bad-fn-ptr-qualifier.rs:11:15 + | +LL | pub 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/bad-fn-ptr-qualifier.rs:15:17 + | +LL | pub type FTT0 = for<'a> const fn(); + | ^^^^^^^^-----^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/bad-fn-ptr-qualifier.rs:16:17 + | +LL | pub type FTT1 = for<'a> const extern "C" fn(); + | ^^^^^^^^-----^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `const` + --> $DIR/bad-fn-ptr-qualifier.rs:17:17 + | +LL | pub type FTT2 = for<'a> const unsafe extern fn(); + | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^ + | | + | `const` because of this + | help: remove the `const` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/bad-fn-ptr-qualifier.rs:18:17 + | +LL | pub type FTT3 = for<'a> async fn(); + | ^^^^^^^^-----^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/bad-fn-ptr-qualifier.rs:19:17 + | +LL | pub type FTT4 = for<'a> async extern fn(); + | ^^^^^^^^-----^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: an `fn` pointer type cannot be `async` + --> $DIR/bad-fn-ptr-qualifier.rs:20:17 + | +LL | pub type FTT5 = 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/bad-fn-ptr-qualifier.rs:22:17 + | +LL | pub type FTT6 = 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/bad-fn-ptr-qualifier.rs:22:17 + | +LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn(); + | ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | help: remove the `async` qualifier + +error: aborting due to 16 previous errors + diff --git a/src/test/ui/parser/bad-if-statements.rs b/src/test/ui/parser/bad-if-statements.rs new file mode 100644 index 000000000..2c501e3a5 --- /dev/null +++ b/src/test/ui/parser/bad-if-statements.rs @@ -0,0 +1,38 @@ +fn a() { + if {} + //~^ ERROR missing condition for `if` expression +} + +fn b() { + if true && {} + //~^ ERROR this `if` expression is missing a block after the condition +} + +fn c() { + let x = {}; + if true x + //~^ ERROR expected `{`, found `x` +} + +fn a2() { + if {} else {} + //~^ ERROR missing condition for `if` expression +} + +fn b2() { + if true && {} else {} + //~^ ERROR this `if` expression is missing a block after the condition +} + +fn c2() { + let x = {}; + if true x else {} + //~^ ERROR expected `{`, found `x` +} + +fn d() { + if true else {} + //~^ ERROR this `if` expression is missing a block after the condition +} + +fn main() {} diff --git a/src/test/ui/parser/bad-if-statements.stderr b/src/test/ui/parser/bad-if-statements.stderr new file mode 100644 index 000000000..ee839db64 --- /dev/null +++ b/src/test/ui/parser/bad-if-statements.stderr @@ -0,0 +1,86 @@ +error: missing condition for `if` expression + --> $DIR/bad-if-statements.rs:2:7 + | +LL | if {} + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: this `if` expression is missing a block after the condition + --> $DIR/bad-if-statements.rs:7:5 + | +LL | if true && {} + | ^^ + | +help: this binary operation is possibly unfinished + --> $DIR/bad-if-statements.rs:7:8 + | +LL | if true && {} + | ^^^^^^^ + +error: expected `{`, found `x` + --> $DIR/bad-if-statements.rs:13:13 + | +LL | if true x + | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/bad-if-statements.rs:13:8 + | +LL | if true x + | ^^^^ +help: try placing this code inside a block + | +LL | if true { x } + | + + + +error: missing condition for `if` expression + --> $DIR/bad-if-statements.rs:18:7 + | +LL | if {} else {} + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: this `if` expression is missing a block after the condition + --> $DIR/bad-if-statements.rs:23:5 + | +LL | if true && {} else {} + | ^^ + | +help: this binary operation is possibly unfinished + --> $DIR/bad-if-statements.rs:23:8 + | +LL | if true && {} else {} + | ^^^^^^^ + +error: expected `{`, found `x` + --> $DIR/bad-if-statements.rs:29:13 + | +LL | if true x else {} + | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/bad-if-statements.rs:29:8 + | +LL | if true x else {} + | ^^^^ +help: try placing this code inside a block + | +LL | if true { x } else {} + | + + + +error: this `if` expression is missing a block after the condition + --> $DIR/bad-if-statements.rs:34:5 + | +LL | if true else {} + | ^^ + | +help: add a block here + --> $DIR/bad-if-statements.rs:34:12 + | +LL | if true else {} + | ^ + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/bad-interpolated-block.rs b/src/test/ui/parser/bad-interpolated-block.rs new file mode 100644 index 000000000..38d53a14b --- /dev/null +++ b/src/test/ui/parser/bad-interpolated-block.rs @@ -0,0 +1,15 @@ +#![feature(label_break_value)] + +fn main() {} + +macro_rules! m { + ($b:block) => { + 'lab: $b; //~ ERROR cannot use a `block` macro fragment here + unsafe $b; //~ ERROR cannot use a `block` macro fragment here + |x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here + } +} + +fn foo() { + m!({}); +} diff --git a/src/test/ui/parser/bad-interpolated-block.stderr b/src/test/ui/parser/bad-interpolated-block.stderr new file mode 100644 index 000000000..77933b1bc --- /dev/null +++ b/src/test/ui/parser/bad-interpolated-block.stderr @@ -0,0 +1,39 @@ +error: cannot use a `block` macro fragment here + --> $DIR/bad-interpolated-block.rs:7:15 + | +LL | 'lab: $b; + | ------^^ + | | + | the `block` fragment is within this context +... +LL | m!({}); + | ------ in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot use a `block` macro fragment here + --> $DIR/bad-interpolated-block.rs:8:16 + | +LL | unsafe $b; + | -------^^ + | | + | the `block` fragment is within this context +... +LL | m!({}); + | ------ in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot use a `block` macro fragment here + --> $DIR/bad-interpolated-block.rs:9:23 + | +LL | |x: u8| -> () $b; + | ^^ the `block` fragment is within this context +... +LL | m!({}); + | ------ in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/bad-lit-suffixes.rs b/src/test/ui/parser/bad-lit-suffixes.rs new file mode 100644 index 000000000..446a09405 --- /dev/null +++ b/src/test/ui/parser/bad-lit-suffixes.rs @@ -0,0 +1,26 @@ +extern + "C"suffix //~ ERROR suffixes on a string literal are invalid + fn foo() {} + +extern + "C"suffix //~ ERROR suffixes on a string literal are invalid +{} + +fn main() { + ""suffix; //~ ERROR suffixes on a string literal are invalid + b""suffix; //~ ERROR suffixes on a byte string literal are invalid + r#""#suffix; //~ ERROR suffixes on a string literal are invalid + br#""#suffix; //~ ERROR suffixes on a byte string literal are invalid + 'a'suffix; //~ ERROR suffixes on a char literal are invalid + b'a'suffix; //~ ERROR suffixes on a byte literal are invalid + + 1234u1024; //~ ERROR invalid width `1024` for integer literal + 1234i1024; //~ ERROR invalid width `1024` for integer literal + 1234f1024; //~ ERROR invalid width `1024` for float literal + 1234.5f1024; //~ ERROR invalid width `1024` for float literal + + 1234suffix; //~ ERROR invalid suffix `suffix` for number literal + 0b101suffix; //~ ERROR invalid suffix `suffix` for number literal + 1.0suffix; //~ ERROR invalid suffix `suffix` for float literal + 1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal +} diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr new file mode 100644 index 000000000..9b5965714 --- /dev/null +++ b/src/test/ui/parser/bad-lit-suffixes.stderr @@ -0,0 +1,114 @@ +error: suffixes on a string literal are invalid + --> $DIR/bad-lit-suffixes.rs:2:5 + | +LL | "C"suffix + | ^^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a string literal are invalid + --> $DIR/bad-lit-suffixes.rs:6:5 + | +LL | "C"suffix + | ^^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a string literal are invalid + --> $DIR/bad-lit-suffixes.rs:10:5 + | +LL | ""suffix; + | ^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a byte string literal are invalid + --> $DIR/bad-lit-suffixes.rs:11:5 + | +LL | b""suffix; + | ^^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a string literal are invalid + --> $DIR/bad-lit-suffixes.rs:12:5 + | +LL | r#""#suffix; + | ^^^^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a byte string literal are invalid + --> $DIR/bad-lit-suffixes.rs:13:5 + | +LL | br#""#suffix; + | ^^^^^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a char literal are invalid + --> $DIR/bad-lit-suffixes.rs:14:5 + | +LL | 'a'suffix; + | ^^^^^^^^^ invalid suffix `suffix` + +error: suffixes on a byte literal are invalid + --> $DIR/bad-lit-suffixes.rs:15:5 + | +LL | b'a'suffix; + | ^^^^^^^^^^ invalid suffix `suffix` + +error: invalid width `1024` for integer literal + --> $DIR/bad-lit-suffixes.rs:17:5 + | +LL | 1234u1024; + | ^^^^^^^^^ + | + = help: valid widths are 8, 16, 32, 64 and 128 + +error: invalid width `1024` for integer literal + --> $DIR/bad-lit-suffixes.rs:18:5 + | +LL | 1234i1024; + | ^^^^^^^^^ + | + = help: valid widths are 8, 16, 32, 64 and 128 + +error: invalid width `1024` for float literal + --> $DIR/bad-lit-suffixes.rs:19:5 + | +LL | 1234f1024; + | ^^^^^^^^^ + | + = help: valid widths are 32 and 64 + +error: invalid width `1024` for float literal + --> $DIR/bad-lit-suffixes.rs:20:5 + | +LL | 1234.5f1024; + | ^^^^^^^^^^^ + | + = help: valid widths are 32 and 64 + +error: invalid suffix `suffix` for number literal + --> $DIR/bad-lit-suffixes.rs:22:5 + | +LL | 1234suffix; + | ^^^^^^^^^^ invalid suffix `suffix` + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +error: invalid suffix `suffix` for number literal + --> $DIR/bad-lit-suffixes.rs:23:5 + | +LL | 0b101suffix; + | ^^^^^^^^^^^ invalid suffix `suffix` + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +error: invalid suffix `suffix` for float literal + --> $DIR/bad-lit-suffixes.rs:24:5 + | +LL | 1.0suffix; + | ^^^^^^^^^ invalid suffix `suffix` + | + = help: valid suffixes are `f32` and `f64` + +error: invalid suffix `suffix` for float literal + --> $DIR/bad-lit-suffixes.rs:25:5 + | +LL | 1.0e10suffix; + | ^^^^^^^^^^^^ invalid suffix `suffix` + | + = help: valid suffixes are `f32` and `f64` + +error: aborting due to 16 previous errors + diff --git a/src/test/ui/parser/bad-match.rs b/src/test/ui/parser/bad-match.rs new file mode 100644 index 000000000..04100d170 --- /dev/null +++ b/src/test/ui/parser/bad-match.rs @@ -0,0 +1,4 @@ +fn main() { + let isize x = 5; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `x` + match x; +} diff --git a/src/test/ui/parser/bad-match.stderr b/src/test/ui/parser/bad-match.stderr new file mode 100644 index 000000000..13784c409 --- /dev/null +++ b/src/test/ui/parser/bad-match.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `x` + --> $DIR/bad-match.rs:2:13 + | +LL | let isize x = 5; + | ^ expected one of `:`, `;`, `=`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-name.rs b/src/test/ui/parser/bad-name.rs new file mode 100644 index 000000000..9b4271692 --- /dev/null +++ b/src/test/ui/parser/bad-name.rs @@ -0,0 +1,5 @@ +// error-pattern: expected + +fn main() { + let x.y::<isize>.z foo; +} diff --git a/src/test/ui/parser/bad-name.stderr b/src/test/ui/parser/bad-name.stderr new file mode 100644 index 000000000..a36b67794 --- /dev/null +++ b/src/test/ui/parser/bad-name.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` + --> $DIR/bad-name.rs:4:8 + | +LL | let x.y::<isize>.z foo; + | ^ expected one of `:`, `;`, `=`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-pointer-type.rs b/src/test/ui/parser/bad-pointer-type.rs new file mode 100644 index 000000000..59e5e0c5d --- /dev/null +++ b/src/test/ui/parser/bad-pointer-type.rs @@ -0,0 +1,5 @@ +fn foo(_: *()) { + //~^ ERROR expected mut or const in raw pointer type +} + +fn main() {} diff --git a/src/test/ui/parser/bad-pointer-type.stderr b/src/test/ui/parser/bad-pointer-type.stderr new file mode 100644 index 000000000..e18c220af --- /dev/null +++ b/src/test/ui/parser/bad-pointer-type.stderr @@ -0,0 +1,10 @@ +error: expected mut or const in raw pointer type + --> $DIR/bad-pointer-type.rs:1:11 + | +LL | fn foo(_: *()) { + | ^ expected mut or const in raw pointer type + | + = help: use `*mut T` or `*const T` as appropriate + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-struct-following-where.rs b/src/test/ui/parser/bad-struct-following-where.rs new file mode 100644 index 000000000..823880b1b --- /dev/null +++ b/src/test/ui/parser/bad-struct-following-where.rs @@ -0,0 +1,2 @@ +struct A where T: Sized ! +//~^ ERROR expected `{` after struct name, found diff --git a/src/test/ui/parser/bad-struct-following-where.stderr b/src/test/ui/parser/bad-struct-following-where.stderr new file mode 100644 index 000000000..bb79776dc --- /dev/null +++ b/src/test/ui/parser/bad-struct-following-where.stderr @@ -0,0 +1,8 @@ +error: expected `{` after struct name, found `!` + --> $DIR/bad-struct-following-where.rs:1:25 + | +LL | struct A where T: Sized ! + | ^ expected `{` after struct name + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-value-ident-false.rs b/src/test/ui/parser/bad-value-ident-false.rs new file mode 100644 index 000000000..4645ab4a7 --- /dev/null +++ b/src/test/ui/parser/bad-value-ident-false.rs @@ -0,0 +1,2 @@ +fn false() { } //~ ERROR expected identifier, found keyword `false` +fn main() { } diff --git a/src/test/ui/parser/bad-value-ident-false.stderr b/src/test/ui/parser/bad-value-ident-false.stderr new file mode 100644 index 000000000..30c05ecf3 --- /dev/null +++ b/src/test/ui/parser/bad-value-ident-false.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `false` + --> $DIR/bad-value-ident-false.rs:1:4 + | +LL | fn false() { } + | ^^^^^ expected identifier, found keyword + | +help: escape `false` to use it as an identifier + | +LL | fn r#false() { } + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bad-value-ident-true.rs b/src/test/ui/parser/bad-value-ident-true.rs new file mode 100644 index 000000000..0f64266d3 --- /dev/null +++ b/src/test/ui/parser/bad-value-ident-true.rs @@ -0,0 +1,2 @@ +fn true() { } //~ ERROR expected identifier, found keyword `true` +fn main() { } diff --git a/src/test/ui/parser/bad-value-ident-true.stderr b/src/test/ui/parser/bad-value-ident-true.stderr new file mode 100644 index 000000000..74137fa70 --- /dev/null +++ b/src/test/ui/parser/bad-value-ident-true.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `true` + --> $DIR/bad-value-ident-true.rs:1:4 + | +LL | fn true() { } + | ^^^^ expected identifier, found keyword + | +help: escape `true` to use it as an identifier + | +LL | fn r#true() { } + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bare-struct-body.rs b/src/test/ui/parser/bare-struct-body.rs new file mode 100644 index 000000000..a557e861d --- /dev/null +++ b/src/test/ui/parser/bare-struct-body.rs @@ -0,0 +1,15 @@ +struct Foo { + val: (), +} + +fn foo() -> Foo { //~ ERROR struct literal body without path + val: (), +} + +fn main() { + let x = foo(); + x.val == 42; //~ ERROR mismatched types + let x = { //~ ERROR struct literal body without path + val: (), + }; +} diff --git a/src/test/ui/parser/bare-struct-body.stderr b/src/test/ui/parser/bare-struct-body.stderr new file mode 100644 index 000000000..c77992b2c --- /dev/null +++ b/src/test/ui/parser/bare-struct-body.stderr @@ -0,0 +1,41 @@ +error: struct literal body without path + --> $DIR/bare-struct-body.rs:5:17 + | +LL | fn foo() -> Foo { + | _________________^ +LL | | val: (), +LL | | } + | |_^ + | +help: you might have forgotten to add the struct literal inside the block + | +LL ~ fn foo() -> Foo { SomeStruct { +LL | val: (), +LL ~ } } + | + +error: struct literal body without path + --> $DIR/bare-struct-body.rs:12:13 + | +LL | let x = { + | _____________^ +LL | | val: (), +LL | | }; + | |_____^ + | +help: you might have forgotten to add the struct literal inside the block + | +LL ~ let x = { SomeStruct { +LL | val: (), +LL ~ } }; + | + +error[E0308]: mismatched types + --> $DIR/bare-struct-body.rs:11:14 + | +LL | x.val == 42; + | ^^ expected `()`, found integer + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/bastion-of-the-turbofish.rs b/src/test/ui/parser/bastion-of-the-turbofish.rs new file mode 100644 index 000000000..e12857008 --- /dev/null +++ b/src/test/ui/parser/bastion-of-the-turbofish.rs @@ -0,0 +1,43 @@ +// check-pass + +// Bastion of the Turbofish +// ------------------------ +// Beware travellers, lest you venture into waters callous and unforgiving, +// where hope must be abandoned, ere it is cruelly torn from you. For here +// stands the bastion of the Turbofish: an impenetrable fortress holding +// unshaking against those who would dare suggest the supererogation of the +// Turbofish. +// +// Once I was young and foolish and had the impudence to imagine that I could +// shake free from the coils by which that creature had us tightly bound. I +// dared to suggest that there was a better way: a brighter future, in which +// Rustaceans both new and old could be rid of that vile beast. But alas! In +// my foolhardiness my ignorance was unveiled and my dreams were dashed +// unforgivingly against the rock of syntactic ambiguity. +// +// This humble program, small and insignificant though it might seem, +// demonstrates that to which we had previously cast a blind eye: an ambiguity +// in permitting generic arguments to be provided without the consent of the +// Great Turbofish. Should you be so naïve as to try to revolt against its +// mighty clutches, here shall its wrath be indomitably displayed. This +// program must pass for all eternity: forever watched by the guardian angel +// which gave this beast its name, and stands fundamentally at odds with the +// impetuous rebellion against the Turbofish. +// +// My heart aches in sorrow, for I know I am defeated. Let this be a warning +// to all those who come after: for they too must overcome the impassible +// hurdle of defeating the great beast, championed by a resolute winged +// guardian. +// +// Here stands the Bastion of the Turbofish, a memorial to Anna Harren, +// Guardian Angel of these Hallowed Grounds. <3 + +// See https://github.com/rust-lang/rust/pull/53562 +// and https://github.com/rust-lang/rfcs/pull/2527 +// and https://twitter.com/garblefart/status/1393236602856611843 +// for context. + +fn main() { + let (the, guardian, stands, resolute) = ("the", "Turbofish", "remains", "undefeated"); + let _: (bool, bool) = (the<guardian, stands>(resolute)); +} diff --git a/src/test/ui/parser/better-expected.rs b/src/test/ui/parser/better-expected.rs new file mode 100644 index 000000000..16b61caa4 --- /dev/null +++ b/src/test/ui/parser/better-expected.rs @@ -0,0 +1,3 @@ +fn main() { + let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3` +} diff --git a/src/test/ui/parser/better-expected.stderr b/src/test/ui/parser/better-expected.stderr new file mode 100644 index 000000000..21bf8d19a --- /dev/null +++ b/src/test/ui/parser/better-expected.stderr @@ -0,0 +1,10 @@ +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3` + --> $DIR/better-expected.rs:2:19 + | +LL | let x: [isize 3]; + | - ^ expected one of 7 possible tokens + | | + | while parsing the type for `x` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bind-struct-early-modifiers.rs b/src/test/ui/parser/bind-struct-early-modifiers.rs new file mode 100644 index 000000000..c4b1937de --- /dev/null +++ b/src/test/ui/parser/bind-struct-early-modifiers.rs @@ -0,0 +1,7 @@ +fn main() { + struct Foo { x: isize } + match (Foo { x: 10 }) { + Foo { ref x: ref x } => {}, //~ ERROR expected `,` + _ => {} + } +} diff --git a/src/test/ui/parser/bind-struct-early-modifiers.stderr b/src/test/ui/parser/bind-struct-early-modifiers.stderr new file mode 100644 index 000000000..b35762a88 --- /dev/null +++ b/src/test/ui/parser/bind-struct-early-modifiers.stderr @@ -0,0 +1,10 @@ +error: expected `,` + --> $DIR/bind-struct-early-modifiers.rs:4:20 + | +LL | Foo { ref x: ref x } => {}, + | --- ^ + | | + | while parsing the fields for this pattern + +error: aborting due to previous error + diff --git a/src/test/ui/parser/block-no-opening-brace.rs b/src/test/ui/parser/block-no-opening-brace.rs new file mode 100644 index 000000000..8a6599488 --- /dev/null +++ b/src/test/ui/parser/block-no-opening-brace.rs @@ -0,0 +1,31 @@ +// edition:2018 + +#![feature(try_blocks)] + +fn main() {} + +fn f1() { + loop + let x = 0; //~ ERROR expected `{`, found keyword `let` + drop(0); + } + +fn f2() { + while true + let x = 0; //~ ERROR expected `{`, found keyword `let` + } + +fn f3() { + for x in 0..1 + let x = 0; //~ ERROR expected `{`, found keyword `let` + } + +fn f4() { + try //~ ERROR expected expression, found reserved keyword `try` + let x = 0; + } + +fn f5() { + async + let x = 0; //~ ERROR expected one of `move`, `|`, or `||`, found keyword `let` + } diff --git a/src/test/ui/parser/block-no-opening-brace.stderr b/src/test/ui/parser/block-no-opening-brace.stderr new file mode 100644 index 000000000..f232f480c --- /dev/null +++ b/src/test/ui/parser/block-no-opening-brace.stderr @@ -0,0 +1,55 @@ +error: expected `{`, found keyword `let` + --> $DIR/block-no-opening-brace.rs:9:9 + | +LL | loop + | ---- while parsing this `loop` expression +LL | let x = 0; + | ^^^ expected `{` + | +help: try placing this code inside a block + | +LL | { let x = 0; } + | + + + +error: expected `{`, found keyword `let` + --> $DIR/block-no-opening-brace.rs:15:9 + | +LL | while true + | ----- ---- this `while` condition successfully parsed + | | + | while parsing the body of this `while` expression +LL | let x = 0; + | ^^^ expected `{` + | +help: try placing this code inside a block + | +LL | { let x = 0; } + | + + + +error: expected `{`, found keyword `let` + --> $DIR/block-no-opening-brace.rs:20:9 + | +LL | let x = 0; + | ^^^ expected `{` + | +help: try placing this code inside a block + | +LL | { let x = 0; } + | + + + +error: expected expression, found reserved keyword `try` + --> $DIR/block-no-opening-brace.rs:24:5 + | +LL | try + | ^^^ expected expression + +error: expected one of `move`, `|`, or `||`, found keyword `let` + --> $DIR/block-no-opening-brace.rs:30:9 + | +LL | async + | - expected one of `move`, `|`, or `||` +LL | let x = 0; + | ^^^ unexpected token + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/parser/bound-single-question-mark.rs b/src/test/ui/parser/bound-single-question-mark.rs new file mode 100644 index 000000000..64d702d14 --- /dev/null +++ b/src/test/ui/parser/bound-single-question-mark.rs @@ -0,0 +1 @@ +fn f<T: ?>() {} //~ ERROR expected identifier, found `>` diff --git a/src/test/ui/parser/bound-single-question-mark.stderr b/src/test/ui/parser/bound-single-question-mark.stderr new file mode 100644 index 000000000..82937a517 --- /dev/null +++ b/src/test/ui/parser/bound-single-question-mark.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `>` + --> $DIR/bound-single-question-mark.rs:1:10 + | +LL | fn f<T: ?>() {} + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-lifetime-1.rs b/src/test/ui/parser/bounds-lifetime-1.rs new file mode 100644 index 000000000..e458f644c --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-1.rs @@ -0,0 +1,3 @@ +type A = for<'a 'b> fn(); //~ ERROR expected one of `,`, `:`, or `>`, found `'b` + +fn main() {} diff --git a/src/test/ui/parser/bounds-lifetime-1.stderr b/src/test/ui/parser/bounds-lifetime-1.stderr new file mode 100644 index 000000000..000e84f63 --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-1.stderr @@ -0,0 +1,8 @@ +error: expected one of `,`, `:`, or `>`, found `'b` + --> $DIR/bounds-lifetime-1.rs:1:17 + | +LL | type A = for<'a 'b> fn(); + | ^^ expected one of `,`, `:`, or `>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-lifetime-2.rs b/src/test/ui/parser/bounds-lifetime-2.rs new file mode 100644 index 000000000..f184107bb --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-2.rs @@ -0,0 +1,3 @@ +type A = for<'a + 'b> fn(); //~ ERROR expected one of `,`, `:`, or `>`, found `+` + +fn main() {} diff --git a/src/test/ui/parser/bounds-lifetime-2.stderr b/src/test/ui/parser/bounds-lifetime-2.stderr new file mode 100644 index 000000000..dd3e69c11 --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-2.stderr @@ -0,0 +1,8 @@ +error: expected one of `,`, `:`, or `>`, found `+` + --> $DIR/bounds-lifetime-2.rs:1:17 + | +LL | type A = for<'a + 'b> fn(); + | ^ expected one of `,`, `:`, or `>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-lifetime-where-1.rs b/src/test/ui/parser/bounds-lifetime-where-1.rs new file mode 100644 index 000000000..f1a002a9f --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-where-1.rs @@ -0,0 +1,3 @@ +type A where 'a; //~ ERROR expected `:`, found `;` + +fn main() {} diff --git a/src/test/ui/parser/bounds-lifetime-where-1.stderr b/src/test/ui/parser/bounds-lifetime-where-1.stderr new file mode 100644 index 000000000..b6bd86693 --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-where-1.stderr @@ -0,0 +1,8 @@ +error: expected `:`, found `;` + --> $DIR/bounds-lifetime-where-1.rs:1:16 + | +LL | type A where 'a; + | ^ expected `:` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-lifetime-where.rs b/src/test/ui/parser/bounds-lifetime-where.rs new file mode 100644 index 000000000..7ff75233d --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-where.rs @@ -0,0 +1,10 @@ +type A where 'a: 'b + 'c = u8; // OK +type A where 'a: 'b, = u8; // OK +type A where 'a: = u8; // OK +type A where 'a:, = u8; // OK +type A where 'a: 'b + 'c = u8; // OK +type A where = u8; // OK +type A where 'a: 'b + = u8; // OK +type A where , = u8; //~ ERROR expected one of `;`, `=`, `where`, lifetime, or type, found `,` + +fn main() {} diff --git a/src/test/ui/parser/bounds-lifetime-where.stderr b/src/test/ui/parser/bounds-lifetime-where.stderr new file mode 100644 index 000000000..785a1fb67 --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime-where.stderr @@ -0,0 +1,8 @@ +error: expected one of `;`, `=`, `where`, lifetime, or type, found `,` + --> $DIR/bounds-lifetime-where.rs:8:14 + | +LL | type A where , = u8; + | ^ expected one of `;`, `=`, `where`, lifetime, or type + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-lifetime.rs b/src/test/ui/parser/bounds-lifetime.rs new file mode 100644 index 000000000..c9251ac53 --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime.rs @@ -0,0 +1,11 @@ +type A = for<'a:> fn(); // OK +type A = for<'a:,> fn(); // OK +type A = for<'a> fn(); // OK +type A = for<> fn(); // OK +type A = for<'a: 'b + 'c> fn(); // OK (rejected later by ast_validation) +type A = for<'a: 'b,> fn(); // OK(rejected later by ast_validation) +type A = for<'a: 'b +> fn(); // OK (rejected later by ast_validation) +type A = for<'a, T> fn(); // OK (rejected later by ast_validation) +type A = for<,> fn(); //~ ERROR expected one of `#`, `>`, `const`, identifier, or lifetime + +fn main() {} diff --git a/src/test/ui/parser/bounds-lifetime.stderr b/src/test/ui/parser/bounds-lifetime.stderr new file mode 100644 index 000000000..e47a21d89 --- /dev/null +++ b/src/test/ui/parser/bounds-lifetime.stderr @@ -0,0 +1,8 @@ +error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,` + --> $DIR/bounds-lifetime.rs:9:14 + | +LL | type A = for<,> fn(); + | ^ expected one of `#`, `>`, `const`, identifier, or lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-obj-parens.rs b/src/test/ui/parser/bounds-obj-parens.rs new file mode 100644 index 000000000..8c446d27d --- /dev/null +++ b/src/test/ui/parser/bounds-obj-parens.rs @@ -0,0 +1,7 @@ +// check-pass + +#![allow(bare_trait_objects)] + +type A = Box<(Fn(u8) -> u8) + 'static + Send + Sync>; // OK (but see #39318) + +fn main() {} diff --git a/src/test/ui/parser/bounds-type-where.rs b/src/test/ui/parser/bounds-type-where.rs new file mode 100644 index 000000000..2520ecb29 --- /dev/null +++ b/src/test/ui/parser/bounds-type-where.rs @@ -0,0 +1,11 @@ +type A where for<'a> for<'b> Trait1 + ?Trait2: 'a + Trait = u8; // OK +type A where T: Trait, = u8; // OK +type A where T: = u8; // OK +type A where T:, = u8; // OK +type A where T: Trait + Trait = u8; // OK +type A where = u8; // OK +type A where T: Trait + = u8; // OK +type A where T, = u8; +//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` + +fn main() {} diff --git a/src/test/ui/parser/bounds-type-where.stderr b/src/test/ui/parser/bounds-type-where.stderr new file mode 100644 index 000000000..5636ee75c --- /dev/null +++ b/src/test/ui/parser/bounds-type-where.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` + --> $DIR/bounds-type-where.rs:8:15 + | +LL | type A where T, = u8; + | ^ expected one of 8 possible tokens + +error: aborting due to previous error + diff --git a/src/test/ui/parser/bounds-type.rs b/src/test/ui/parser/bounds-type.rs new file mode 100644 index 000000000..4ae4549ea --- /dev/null +++ b/src/test/ui/parser/bounds-type.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z parse-only + +struct S< + T: 'a + Tr, // OK + T: Tr + 'a, // OK + T: 'a, // OK + T:, // OK + T: ?for<'a> Trait, // OK + T: Tr +, // OK + T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds + + T: ~const Tr, // OK + T: ~const ?Tr, // OK + T: ~const Tr + 'a, // OK + T: ~const 'a, //~ ERROR `~const` may only modify trait bounds, not lifetime bounds +>; + +fn main() {} diff --git a/src/test/ui/parser/bounds-type.stderr b/src/test/ui/parser/bounds-type.stderr new file mode 100644 index 000000000..005bc1e54 --- /dev/null +++ b/src/test/ui/parser/bounds-type.stderr @@ -0,0 +1,14 @@ +error: `?` may only modify trait bounds, not lifetime bounds + --> $DIR/bounds-type.rs:10:8 + | +LL | T: ?'a, + | ^ + +error: `~const` may only modify trait bounds, not lifetime bounds + --> $DIR/bounds-type.rs:15:8 + | +LL | T: ~const 'a, + | ^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs new file mode 100644 index 000000000..05a510b24 --- /dev/null +++ b/src/test/ui/parser/byte-literals.rs @@ -0,0 +1,12 @@ +// ignore-tidy-tab + +static FOO: u8 = b'\f'; //~ ERROR unknown byte escape + +pub fn main() { + b'\f'; //~ ERROR unknown byte escape + b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z` + b' '; //~ ERROR byte constant must be escaped + b'''; //~ ERROR byte constant must be escaped + b'é'; //~ ERROR non-ASCII character in byte constant + b'a //~ ERROR unterminated byte constant [E0763] +} diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr new file mode 100644 index 000000000..c3d000616 --- /dev/null +++ b/src/test/ui/parser/byte-literals.stderr @@ -0,0 +1,54 @@ +error: unknown byte escape: `f` + --> $DIR/byte-literals.rs:3:21 + | +LL | static FOO: u8 = b'\f'; + | ^ unknown byte escape + | + = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + +error: unknown byte escape: `f` + --> $DIR/byte-literals.rs:6:8 + | +LL | b'\f'; + | ^ unknown byte escape + | + = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + +error: invalid character in numeric character escape: `Z` + --> $DIR/byte-literals.rs:7:10 + | +LL | b'\x0Z'; + | ^ invalid character in numeric character escape + +error: byte constant must be escaped: `\t` + --> $DIR/byte-literals.rs:8:7 + | +LL | b' '; + | ^^^^ help: escape the character: `\t` + +error: byte constant must be escaped: `'` + --> $DIR/byte-literals.rs:9:7 + | +LL | b'''; + | ^ help: escape the character: `\'` + +error: non-ASCII character in byte constant + --> $DIR/byte-literals.rs:10:7 + | +LL | b'é'; + | ^ byte constant must be ASCII + | +help: if you meant to use the unicode code point for 'é', use a \xHH escape + | +LL | b'\xE9'; + | ~~~~ + +error[E0763]: unterminated byte constant + --> $DIR/byte-literals.rs:11:6 + | +LL | b'a + | ^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0763`. diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs new file mode 100644 index 000000000..b1f11024a --- /dev/null +++ b/src/test/ui/parser/byte-string-literals.rs @@ -0,0 +1,9 @@ +static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape + +pub fn main() { + b"\f"; //~ ERROR unknown byte escape + b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z` + b"é"; //~ ERROR non-ASCII character in byte constant + br##"é"##; //~ ERROR raw byte string must be ASCII + b"a //~ ERROR unterminated double quote byte string +} diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr new file mode 100644 index 000000000..3b8b3692e --- /dev/null +++ b/src/test/ui/parser/byte-string-literals.stderr @@ -0,0 +1,50 @@ +error: unknown byte escape: `f` + --> $DIR/byte-string-literals.rs:1:32 + | +LL | static FOO: &'static [u8] = b"\f"; + | ^ unknown byte escape + | + = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + +error: unknown byte escape: `f` + --> $DIR/byte-string-literals.rs:4:8 + | +LL | b"\f"; + | ^ unknown byte escape + | + = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + +error: invalid character in numeric character escape: `Z` + --> $DIR/byte-string-literals.rs:5:10 + | +LL | b"\x0Z"; + | ^ invalid character in numeric character escape + +error: non-ASCII character in byte constant + --> $DIR/byte-string-literals.rs:6:7 + | +LL | b"é"; + | ^ byte constant must be ASCII + | +help: if you meant to use the unicode code point for 'é', use a \xHH escape + | +LL | b"\xE9"; + | ~~~~ + +error: raw byte string must be ASCII + --> $DIR/byte-string-literals.rs:7:10 + | +LL | br##"é"##; + | ^ must be ASCII + +error[E0766]: unterminated double quote byte string + --> $DIR/byte-string-literals.rs:8:6 + | +LL | b"a + | ______^ +LL | | } + | |__^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0766`. diff --git a/src/test/ui/parser/can-begin-expr-check.rs b/src/test/ui/parser/can-begin-expr-check.rs new file mode 100644 index 000000000..e5be8de79 --- /dev/null +++ b/src/test/ui/parser/can-begin-expr-check.rs @@ -0,0 +1,20 @@ +pub fn main() { + + return; + return (); + return as (); + return return as (); + return return return; + + return if true { + () + } else { + () + }; + + loop { + return break as (); + } + + return enum; //~ ERROR expected one of `;`, `}`, or an operator, found keyword `enum` +} diff --git a/src/test/ui/parser/can-begin-expr-check.stderr b/src/test/ui/parser/can-begin-expr-check.stderr new file mode 100644 index 000000000..9569ababa --- /dev/null +++ b/src/test/ui/parser/can-begin-expr-check.stderr @@ -0,0 +1,8 @@ +error: expected one of `;`, `}`, or an operator, found keyword `enum` + --> $DIR/can-begin-expr-check.rs:19:12 + | +LL | return enum; + | ^^^^ expected one of `;`, `}`, or an operator + +error: aborting due to previous error + diff --git a/src/test/ui/parser/chained-comparison-suggestion.rs b/src/test/ui/parser/chained-comparison-suggestion.rs new file mode 100644 index 000000000..bbd46082c --- /dev/null +++ b/src/test/ui/parser/chained-comparison-suggestion.rs @@ -0,0 +1,53 @@ +// Check that we get nice suggestions when attempting a chained comparison. + +fn comp1() { + 1 < 2 <= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp2() { + 1 < 2 < 3; //~ ERROR comparison operators cannot be chained +} + +fn comp3() { + 1 <= 2 < 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp4() { + 1 <= 2 <= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp5() { + 1 > 2 >= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp6() { + 1 > 2 > 3; //~ ERROR comparison operators cannot be chained +} + +fn comp7() { + 1 >= 2 > 3; //~ ERROR comparison operators cannot be chained +} + +fn comp8() { + 1 >= 2 >= 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn comp9() { + 1 == 2 < 3; //~ ERROR comparison operators cannot be chained +} + +fn comp10() { + 1 > 2 == false; //~ ERROR comparison operators cannot be chained +} + +fn comp11() { + 1 == 2 == 3; //~ ERROR comparison operators cannot be chained + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/parser/chained-comparison-suggestion.stderr b/src/test/ui/parser/chained-comparison-suggestion.stderr new file mode 100644 index 000000000..694b0b6eb --- /dev/null +++ b/src/test/ui/parser/chained-comparison-suggestion.stderr @@ -0,0 +1,160 @@ +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:4:7 + | +LL | 1 < 2 <= 3; + | ^ ^^ + | +help: split the comparison into two + | +LL | 1 < 2 && 2 <= 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:9:7 + | +LL | 1 < 2 < 3; + | ^ ^ + | +help: split the comparison into two + | +LL | 1 < 2 && 2 < 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:13:7 + | +LL | 1 <= 2 < 3; + | ^^ ^ + | +help: split the comparison into two + | +LL | 1 <= 2 && 2 < 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:18:7 + | +LL | 1 <= 2 <= 3; + | ^^ ^^ + | +help: split the comparison into two + | +LL | 1 <= 2 && 2 <= 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:23:7 + | +LL | 1 > 2 >= 3; + | ^ ^^ + | +help: split the comparison into two + | +LL | 1 > 2 && 2 >= 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:28:7 + | +LL | 1 > 2 > 3; + | ^ ^ + | +help: split the comparison into two + | +LL | 1 > 2 && 2 > 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:32:7 + | +LL | 1 >= 2 > 3; + | ^^ ^ + | +help: split the comparison into two + | +LL | 1 >= 2 && 2 > 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:36:7 + | +LL | 1 >= 2 >= 3; + | ^^ ^^ + | +help: split the comparison into two + | +LL | 1 >= 2 && 2 >= 3; + | ++++ + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:41:7 + | +LL | 1 == 2 < 3; + | ^^ ^ + | +help: parenthesize the comparison + | +LL | 1 == (2 < 3); + | + + + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:45:7 + | +LL | 1 > 2 == false; + | ^ ^^ + | +help: parenthesize the comparison + | +LL | (1 > 2) == false; + | + + + +error: comparison operators cannot be chained + --> $DIR/chained-comparison-suggestion.rs:49:7 + | +LL | 1 == 2 == 3; + | ^^ ^^ + | +help: split the comparison into two + | +LL | 1 == 2 && 2 == 3; + | ++++ + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:4:14 + | +LL | 1 < 2 <= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:13:14 + | +LL | 1 <= 2 < 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:18:15 + | +LL | 1 <= 2 <= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:23:14 + | +LL | 1 > 2 >= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:36:15 + | +LL | 1 >= 2 >= 3; + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/chained-comparison-suggestion.rs:49:15 + | +LL | 1 == 2 == 3; + | ^ expected `bool`, found integer + +error: aborting due to 17 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/char/whitespace-character-literal.rs b/src/test/ui/parser/char/whitespace-character-literal.rs new file mode 100644 index 000000000..de5e09204 --- /dev/null +++ b/src/test/ui/parser/char/whitespace-character-literal.rs @@ -0,0 +1,10 @@ +// This tests that the error generated when a character literal has multiple +// characters in it contains a note about non-printing characters. + +fn main() { + let _hair_space_around = ' x'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` + //~| HELP: consider removing the non-printing characters + //~| SUGGESTION: x +} diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr new file mode 100644 index 000000000..d73de41a8 --- /dev/null +++ b/src/test/ui/parser/char/whitespace-character-literal.stderr @@ -0,0 +1,16 @@ +error: character literal may only contain one codepoint + --> $DIR/whitespace-character-literal.rs:5:30 + | +LL | let _hair_space_around = ' x'; + | ^--^ + | | + | help: consider removing the non-printing characters: `x` + | +note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` + --> $DIR/whitespace-character-literal.rs:5:31 + | +LL | let _hair_space_around = ' x'; + | ^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/circular_modules_hello.rs b/src/test/ui/parser/circular_modules_hello.rs new file mode 100644 index 000000000..6968ca97b --- /dev/null +++ b/src/test/ui/parser/circular_modules_hello.rs @@ -0,0 +1,8 @@ +// ignore-test: this is an auxiliary file for circular-modules-main.rs + +#[path = "circular_modules_main.rs"] +mod circular_modules_main; + +pub fn say_hello() { + println!("{}", circular_modules_main::hi_str()); +} diff --git a/src/test/ui/parser/circular_modules_main.rs b/src/test/ui/parser/circular_modules_main.rs new file mode 100644 index 000000000..d4b47efe6 --- /dev/null +++ b/src/test/ui/parser/circular_modules_main.rs @@ -0,0 +1,12 @@ +// error-pattern: circular modules + +#[path = "circular_modules_hello.rs"] +mod circular_modules_hello; + +pub fn hi_str() -> String { + "Hi!".to_string() +} + +fn main() { + circular_modules_hello::say_hello(); +} diff --git a/src/test/ui/parser/circular_modules_main.stderr b/src/test/ui/parser/circular_modules_main.stderr new file mode 100644 index 000000000..1094def60 --- /dev/null +++ b/src/test/ui/parser/circular_modules_main.stderr @@ -0,0 +1,25 @@ +error: circular modules: $DIR/circular_modules_main.rs -> $DIR/circular_modules_hello.rs -> $DIR/circular_modules_main.rs + --> $DIR/circular_modules_hello.rs:4:1 + | +LL | mod circular_modules_main; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0425]: cannot find function `hi_str` in module `circular_modules_main` + --> $DIR/circular_modules_hello.rs:7:43 + | +LL | println!("{}", circular_modules_main::hi_str()); + | ^^^^^^ not found in `circular_modules_main` + | +help: consider importing this function + | +LL | use hi_str; + | +help: if you import `hi_str`, refer to it directly + | +LL - println!("{}", circular_modules_main::hi_str()); +LL + println!("{}", hi_str()); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/class-implements-bad-trait.rs b/src/test/ui/parser/class-implements-bad-trait.rs new file mode 100644 index 000000000..f2f85d026 --- /dev/null +++ b/src/test/ui/parser/class-implements-bad-trait.rs @@ -0,0 +1,9 @@ +// error-pattern:nonexistent +class cat : nonexistent { + let meows: usize; + new(in_x : usize) { self.meows = in_x; } +} + +fn main() { + let nyan = cat(0); +} diff --git a/src/test/ui/parser/class-implements-bad-trait.stderr b/src/test/ui/parser/class-implements-bad-trait.stderr new file mode 100644 index 000000000..3a4dea95d --- /dev/null +++ b/src/test/ui/parser/class-implements-bad-trait.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `::`, found `cat` + --> $DIR/class-implements-bad-trait.rs:2:7 + | +LL | class cat : nonexistent { + | ^^^ expected one of `!` or `::` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/closure-return-syntax.rs b/src/test/ui/parser/closure-return-syntax.rs new file mode 100644 index 000000000..c6a08abef --- /dev/null +++ b/src/test/ui/parser/closure-return-syntax.rs @@ -0,0 +1,7 @@ +// Test that we cannot parse a closure with an explicit return type +// unless it uses braces. + +fn main() { + let x = || -> i32 22; + //~^ ERROR expected `{`, found `22` +} diff --git a/src/test/ui/parser/closure-return-syntax.stderr b/src/test/ui/parser/closure-return-syntax.stderr new file mode 100644 index 000000000..3d16a2067 --- /dev/null +++ b/src/test/ui/parser/closure-return-syntax.stderr @@ -0,0 +1,13 @@ +error: expected `{`, found `22` + --> $DIR/closure-return-syntax.rs:5:23 + | +LL | let x = || -> i32 22; + | ^^ expected `{` + | +help: try placing this code inside a block + | +LL | let x = || -> i32 { 22 }; + | + + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/column-offset-1-based.rs b/src/test/ui/parser/column-offset-1-based.rs new file mode 100644 index 000000000..0c24478c2 --- /dev/null +++ b/src/test/ui/parser/column-offset-1-based.rs @@ -0,0 +1 @@ +# //~ ERROR expected one of `!` or `[`, found `<eof>` diff --git a/src/test/ui/parser/column-offset-1-based.stderr b/src/test/ui/parser/column-offset-1-based.stderr new file mode 100644 index 000000000..766d72a0a --- /dev/null +++ b/src/test/ui/parser/column-offset-1-based.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `[`, found `<eof>` + --> $DIR/column-offset-1-based.rs:1:1 + | +LL | # + | ^ expected one of `!` or `[` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs new file mode 100644 index 000000000..53e3c6f96 --- /dev/null +++ b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs @@ -0,0 +1,15 @@ +struct NInts<const N: usize>([u8; N]); +impl NInts<const N: usize> {} //~ ERROR unexpected `const` parameter declaration + +fn main() { + let _: () = 42; //~ ERROR mismatched types +} + +fn banana(a: <T<const N: usize>>::BAR) {} +//~^ ERROR unexpected `const` parameter declaration +//~| ERROR cannot find type `T` in this scope +fn chaenomeles() { + path::path::Struct::<const N: usize>() + //~^ ERROR unexpected `const` parameter declaration + //~| ERROR failed to resolve: use of undeclared crate or module `path` +} diff --git a/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr new file mode 100644 index 000000000..96885d11e --- /dev/null +++ b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr @@ -0,0 +1,47 @@ +error: unexpected `const` parameter declaration + --> $DIR/const-param-decl-on-type-instead-of-impl.rs:2:12 + | +LL | impl NInts<const N: usize> {} + | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration + | +help: `const` parameters must be declared for the `impl` + | +LL | impl<const N: usize> NInts<N> {} + | ++++++++++++++++ ~ + +error: unexpected `const` parameter declaration + --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:17 + | +LL | fn banana(a: <T<const N: usize>>::BAR) {} + | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration + +error: unexpected `const` parameter declaration + --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:26 + | +LL | path::path::Struct::<const N: usize>() + | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration + +error[E0433]: failed to resolve: use of undeclared crate or module `path` + --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:5 + | +LL | path::path::Struct::<const N: usize>() + | ^^^^ use of undeclared crate or module `path` + +error[E0412]: cannot find type `T` in this scope + --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15 + | +LL | fn banana(a: <T<const N: usize>>::BAR) {} + | ^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/const-param-decl-on-type-instead-of-impl.rs:5:17 + | +LL | let _: () = 42; + | -- ^^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0412, E0433. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs new file mode 100644 index 000000000..afbd13e6f --- /dev/null +++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs @@ -0,0 +1,9 @@ +// check-pass + +#[cfg(FALSE)] +fn syntax() { + foo::<T = u8, T: Ord, String>(); + foo::<T = u8, 'a, T: Ord>(); +} + +fn main() {} diff --git a/src/test/ui/parser/default-on-wrong-item-kind.rs b/src/test/ui/parser/default-on-wrong-item-kind.rs new file mode 100644 index 000000000..98a95cfa3 --- /dev/null +++ b/src/test/ui/parser/default-on-wrong-item-kind.rs @@ -0,0 +1,140 @@ +// Test parsing for `default` where it doesn't belong. +// Specifically, we are interested in kinds of items or items in certain contexts. +// Also test item kinds in `extern` blocks and associated contexts which are not allowed there. + +fn main() {} + +#[cfg(FALSE)] +mod free_items { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + default use foo; //~ ERROR a `use` import cannot be `default` + default static foo: u8; //~ ERROR a static item cannot be `default` + default const foo: u8; + default fn foo(); + default mod foo {} //~ ERROR a module cannot be `default` + default extern "C" {} //~ ERROR an extern block cannot be `default` + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + default struct foo {} //~ ERROR a struct cannot be `default` + default union foo {} //~ ERROR a union cannot be `default` + default trait foo {} //~ ERROR a trait cannot be `default` + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + default impl foo {} + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` +} + +#[cfg(FALSE)] +extern "C" { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + //~^ ERROR extern crate is not supported in `extern` blocks + default use foo; //~ ERROR a `use` import cannot be `default` + //~^ ERROR `use` import is not supported in `extern` blocks + default static foo: u8; //~ ERROR a static item cannot be `default` + default const foo: u8; + //~^ ERROR extern items cannot be `const` + default fn foo(); + default mod foo {} //~ ERROR a module cannot be `default` + //~^ ERROR module is not supported in `extern` blocks + default extern "C" {} //~ ERROR an extern block cannot be `default` + //~^ ERROR extern block is not supported in `extern` blocks + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + //~^ ERROR enum is not supported in `extern` blocks + default struct foo {} //~ ERROR a struct cannot be `default` + //~^ ERROR struct is not supported in `extern` blocks + default union foo {} //~ ERROR a union cannot be `default` + //~^ ERROR union is not supported in `extern` blocks + default trait foo {} //~ ERROR a trait cannot be `default` + //~^ ERROR trait is not supported in `extern` blocks + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + //~^ ERROR trait alias is not supported in `extern` blocks + default impl foo {} + //~^ ERROR implementation is not supported in `extern` blocks + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `extern` blocks + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `extern` blocks +} + +#[cfg(FALSE)] +impl S { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + //~^ ERROR extern crate is not supported in `trait`s or `impl`s + default use foo; //~ ERROR a `use` import cannot be `default` + //~^ ERROR `use` import is not supported in `trait`s or `impl`s + default static foo: u8; //~ ERROR a static item cannot be `default` + //~^ ERROR associated `static` items are not allowed + default const foo: u8; + default fn foo(); + default mod foo {}//~ ERROR a module cannot be `default` + //~^ ERROR module is not supported in `trait`s or `impl`s + default extern "C" {} //~ ERROR an extern block cannot be `default` + //~^ ERROR extern block is not supported in `trait`s or `impl`s + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + //~^ ERROR enum is not supported in `trait`s or `impl`s + default struct foo {} //~ ERROR a struct cannot be `default` + //~^ ERROR struct is not supported in `trait`s or `impl`s + default union foo {} //~ ERROR a union cannot be `default` + //~^ ERROR union is not supported in `trait`s or `impl`s + default trait foo {} //~ ERROR a trait cannot be `default` + //~^ ERROR trait is not supported in `trait`s or `impl`s + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + //~^ ERROR trait alias is not supported in `trait`s or `impl`s + default impl foo {} + //~^ ERROR implementation is not supported in `trait`s or `impl`s + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s +} + +#[cfg(FALSE)] +trait T { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + //~^ ERROR extern crate is not supported in `trait`s or `impl`s + default use foo; //~ ERROR a `use` import cannot be `default` + //~^ ERROR `use` import is not supported in `trait`s or `impl`s + default static foo: u8; //~ ERROR a static item cannot be `default` + //~^ ERROR associated `static` items are not allowed + default const foo: u8; + default fn foo(); + default mod foo {}//~ ERROR a module cannot be `default` + //~^ ERROR module is not supported in `trait`s or `impl`s + default extern "C" {} //~ ERROR an extern block cannot be `default` + //~^ ERROR extern block is not supported in `trait`s or `impl`s + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + //~^ ERROR enum is not supported in `trait`s or `impl`s + default struct foo {} //~ ERROR a struct cannot be `default` + //~^ ERROR struct is not supported in `trait`s or `impl`s + default union foo {} //~ ERROR a union cannot be `default` + //~^ ERROR union is not supported in `trait`s or `impl`s + default trait foo {} //~ ERROR a trait cannot be `default` + //~^ ERROR trait is not supported in `trait`s or `impl`s + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + //~^ ERROR trait alias is not supported in `trait`s or `impl`s + default impl foo {} + //~^ ERROR implementation is not supported in `trait`s or `impl`s + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s +} diff --git a/src/test/ui/parser/default-on-wrong-item-kind.stderr b/src/test/ui/parser/default-on-wrong-item-kind.stderr new file mode 100644 index 000000000..af513f761 --- /dev/null +++ b/src/test/ui/parser/default-on-wrong-item-kind.stderr @@ -0,0 +1,760 @@ +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:9:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:10:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:11:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:14:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:15:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:17:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:18:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:19:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:20:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:21:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:25:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:26:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:27:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:28:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:33:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern crate is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:33:5 + | +LL | default extern crate foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern crate out to a nearby module scope + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:35:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: `use` import is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:35:5 + | +LL | default use foo; + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the `use` import out to a nearby module scope + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:37:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern items cannot be `const` + --> $DIR/default-on-wrong-item-kind.rs:38:19 + | +LL | default const foo: u8; + | --------------^^^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:41:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: module is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:41:5 + | +LL | default mod foo {} + | ^^^^^^^^^^^^^^^ + | + = help: consider moving the module out to a nearby module scope + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:43:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern block is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:43:5 + | +LL | default extern "C" {} + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern block out to a nearby module scope + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:46:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: enum is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:46:5 + | +LL | default enum foo {} + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the enum out to a nearby module scope + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:48:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: struct is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:48:5 + | +LL | default struct foo {} + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:50:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: union is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:50:5 + | +LL | default union foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the union out to a nearby module scope + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:52:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:52:5 + | +LL | default trait foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:54:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait alias is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:54:5 + | +LL | default trait foo = Ord; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait alias out to a nearby module scope + +error: implementation is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:56:5 + | +LL | default impl foo {} + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:60:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:61:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:62:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:62:5 + | +LL | default macro foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:64:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:64:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope + +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:70:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern crate is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:70:5 + | +LL | default extern crate foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern crate out to a nearby module scope + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:72:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: `use` import is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:72:5 + | +LL | default use foo; + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the `use` import out to a nearby module scope + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:74:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/default-on-wrong-item-kind.rs:74:5 + | +LL | default static foo: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:78:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: module is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:78:5 + | +LL | default mod foo {} + | ^^^^^^^^^^^^^^^ + | + = help: consider moving the module out to a nearby module scope + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:80:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern block is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:80:5 + | +LL | default extern "C" {} + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern block out to a nearby module scope + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:83:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:83:5 + | +LL | default enum foo {} + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the enum out to a nearby module scope + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:85:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:85:5 + | +LL | default struct foo {} + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:87:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: union is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:87:5 + | +LL | default union foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the union out to a nearby module scope + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:89:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:89:5 + | +LL | default trait foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:91:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait alias is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:91:5 + | +LL | default trait foo = Ord; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait alias out to a nearby module scope + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:93:5 + | +LL | default impl foo {} + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:97:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:98:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:99:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:99:5 + | +LL | default macro foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:101:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:101:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope + +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:107:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern crate is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:107:5 + | +LL | default extern crate foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern crate out to a nearby module scope + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:109:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: `use` import is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:109:5 + | +LL | default use foo; + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the `use` import out to a nearby module scope + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:111:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/default-on-wrong-item-kind.rs:111:5 + | +LL | default static foo: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:115:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: module is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:115:5 + | +LL | default mod foo {} + | ^^^^^^^^^^^^^^^ + | + = help: consider moving the module out to a nearby module scope + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:117:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern block is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:117:5 + | +LL | default extern "C" {} + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern block out to a nearby module scope + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:120:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:120:5 + | +LL | default enum foo {} + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the enum out to a nearby module scope + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:122:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:122:5 + | +LL | default struct foo {} + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:124:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: union is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:124:5 + | +LL | default union foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the union out to a nearby module scope + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:126:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:126:5 + | +LL | default trait foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:128:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait alias is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:128:5 + | +LL | default trait foo = Ord; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait alias out to a nearby module scope + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:130:5 + | +LL | default impl foo {} + | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:134:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:135:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:136:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:136:5 + | +LL | default macro foo {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:138:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:138:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope + +error: aborting due to 95 previous errors + diff --git a/src/test/ui/parser/default-unmatched-assoc.rs b/src/test/ui/parser/default-unmatched-assoc.rs new file mode 100644 index 000000000..168ea3e76 --- /dev/null +++ b/src/test/ui/parser/default-unmatched-assoc.rs @@ -0,0 +1,16 @@ +fn main() {} + +trait Foo { + default!(); //~ ERROR cannot find macro `default` in this scope + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} + +struct S; +impl S { + default!(); //~ ERROR cannot find macro `default` in this scope + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} diff --git a/src/test/ui/parser/default-unmatched-assoc.stderr b/src/test/ui/parser/default-unmatched-assoc.stderr new file mode 100644 index 000000000..ee35fded9 --- /dev/null +++ b/src/test/ui/parser/default-unmatched-assoc.stderr @@ -0,0 +1,54 @@ +error: `default` is not followed by an item + --> $DIR/default-unmatched-assoc.rs:5:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default-unmatched-assoc.rs:5:13 + | +LL | trait Foo { + | - item list starts here +LL | default!(); +LL | default do + | ^^ non-item starts here +... +LL | } + | - item list ends here + +error: `default` is not followed by an item + --> $DIR/default-unmatched-assoc.rs:13:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default-unmatched-assoc.rs:13:13 + | +LL | impl S { + | - item list starts here +LL | default!(); +LL | default do + | ^^ non-item starts here +... +LL | } + | - item list ends here + +error: cannot find macro `default` in this scope + --> $DIR/default-unmatched-assoc.rs:4:5 + | +LL | default!(); + | ^^^^^^^ + +error: cannot find macro `default` in this scope + --> $DIR/default-unmatched-assoc.rs:12:5 + | +LL | default!(); + | ^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/default-unmatched-extern.rs b/src/test/ui/parser/default-unmatched-extern.rs new file mode 100644 index 000000000..8d0ea590f --- /dev/null +++ b/src/test/ui/parser/default-unmatched-extern.rs @@ -0,0 +1,8 @@ +fn main() {} + +extern "C" { + default!(); //~ ERROR cannot find macro `default` in this scope + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} diff --git a/src/test/ui/parser/default-unmatched-extern.stderr b/src/test/ui/parser/default-unmatched-extern.stderr new file mode 100644 index 000000000..bb4efd516 --- /dev/null +++ b/src/test/ui/parser/default-unmatched-extern.stderr @@ -0,0 +1,28 @@ +error: `default` is not followed by an item + --> $DIR/default-unmatched-extern.rs:5:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default-unmatched-extern.rs:5:13 + | +LL | extern "C" { + | - item list starts here +LL | default!(); +LL | default do + | ^^ non-item starts here +... +LL | } + | - item list ends here + +error: cannot find macro `default` in this scope + --> $DIR/default-unmatched-extern.rs:4:5 + | +LL | default!(); + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/default-unmatched.rs b/src/test/ui/parser/default-unmatched.rs new file mode 100644 index 000000000..49346e5c6 --- /dev/null +++ b/src/test/ui/parser/default-unmatched.rs @@ -0,0 +1,6 @@ +mod foo { + default!(); // OK. + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR expected item, found reserved keyword `do` +} diff --git a/src/test/ui/parser/default-unmatched.stderr b/src/test/ui/parser/default-unmatched.stderr new file mode 100644 index 000000000..331e003f6 --- /dev/null +++ b/src/test/ui/parser/default-unmatched.stderr @@ -0,0 +1,16 @@ +error: `default` is not followed by an item + --> $DIR/default-unmatched.rs:3:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: expected item, found reserved keyword `do` + --> $DIR/default-unmatched.rs:3:13 + | +LL | default do + | ^^ expected item + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/default.rs b/src/test/ui/parser/default.rs new file mode 100644 index 000000000..52338c1f1 --- /dev/null +++ b/src/test/ui/parser/default.rs @@ -0,0 +1,28 @@ +// Test successful and unsuccessful parsing of the `default` contextual keyword + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +trait Foo { + fn foo<T: Default>() -> T; +} + +impl Foo for u8 { + default fn foo<T: Default>() -> T { + T::default() + } +} + +impl Foo for u16 { + pub default fn foo<T: Default>() -> T { //~ ERROR unnecessary visibility qualifier + T::default() + } +} + +impl Foo for u32 { //~ ERROR not all trait items implemented, missing: `foo` + default pub fn foo<T: Default>() -> T { T::default() } + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} + +fn main() {} diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr new file mode 100644 index 000000000..5b763ae72 --- /dev/null +++ b/src/test/ui/parser/default.stderr @@ -0,0 +1,48 @@ +error: `default` is not followed by an item + --> $DIR/default.rs:23:5 + | +LL | default pub fn foo<T: Default>() -> T { T::default() } + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default.rs:23:13 + | +LL | impl Foo for u32 { + | - item list starts here +LL | default pub fn foo<T: Default>() -> T { T::default() } + | ^^^ non-item starts here +... +LL | } + | - item list ends here + +error[E0449]: unnecessary visibility qualifier + --> $DIR/default.rs:17:5 + | +LL | pub default fn foo<T: Default>() -> T { + | ^^^ `pub` not permitted here because it's implied + +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/default.rs:22:1 + | +LL | fn foo<T: Default>() -> T; + | -------------------------- `foo` from trait +... +LL | impl Foo for u32 { + | ^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to 4 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0046, E0449. +For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/parser/do-catch-suggests-try.rs b/src/test/ui/parser/do-catch-suggests-try.rs new file mode 100644 index 000000000..f64568d06 --- /dev/null +++ b/src/test/ui/parser/do-catch-suggests-try.rs @@ -0,0 +1,10 @@ +#![feature(try_blocks)] + +fn main() { + let _: Option<()> = do catch {}; + //~^ ERROR found removed `do catch` syntax + //~| replace with the new syntax + //~| following RFC #2388, the new non-placeholder syntax is `try` + + let _recovery_witness: () = 1; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/do-catch-suggests-try.stderr b/src/test/ui/parser/do-catch-suggests-try.stderr new file mode 100644 index 000000000..cd8907b7e --- /dev/null +++ b/src/test/ui/parser/do-catch-suggests-try.stderr @@ -0,0 +1,19 @@ +error: found removed `do catch` syntax + --> $DIR/do-catch-suggests-try.rs:4:25 + | +LL | let _: Option<()> = do catch {}; + | ^^^^^^^^ help: replace with the new syntax: `try` + | + = note: following RFC #2388, the new non-placeholder syntax is `try` + +error[E0308]: mismatched types + --> $DIR/do-catch-suggests-try.rs:9:33 + | +LL | let _recovery_witness: () = 1; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/doc-after-struct-field.rs b/src/test/ui/parser/doc-after-struct-field.rs new file mode 100644 index 000000000..5b6f08036 --- /dev/null +++ b/src/test/ui/parser/doc-after-struct-field.rs @@ -0,0 +1,16 @@ +struct X { + a: u8 /** document a */, + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended +} + +struct Y { + a: u8 /// document a + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended +} + +fn main() { + let x = X { a: 1 }; + let y = Y { a: 1 }; +} diff --git a/src/test/ui/parser/doc-after-struct-field.stderr b/src/test/ui/parser/doc-after-struct-field.stderr new file mode 100644 index 000000000..e3b32a7f0 --- /dev/null +++ b/src/test/ui/parser/doc-after-struct-field.stderr @@ -0,0 +1,19 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-after-struct-field.rs:2:11 + | +LL | a: u8 /** document a */, + | ^^^^^^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-after-struct-field.rs:8:11 + | +LL | a: u8 /// document a + | ^^^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/doc-before-attr.rs b/src/test/ui/parser/doc-before-attr.rs new file mode 100644 index 000000000..c4125a09f --- /dev/null +++ b/src/test/ui/parser/doc-before-attr.rs @@ -0,0 +1,4 @@ +fn main() {} + +/// hi +#[derive(Debug)] //~ERROR expected item after attributes diff --git a/src/test/ui/parser/doc-before-attr.stderr b/src/test/ui/parser/doc-before-attr.stderr new file mode 100644 index 000000000..14fd01af2 --- /dev/null +++ b/src/test/ui/parser/doc-before-attr.stderr @@ -0,0 +1,10 @@ +error: expected item after attributes + --> $DIR/doc-before-attr.rs:4:1 + | +LL | /// hi + | ------ other attributes here +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/doc-before-eof.rs b/src/test/ui/parser/doc-before-eof.rs new file mode 100644 index 000000000..b31836e95 --- /dev/null +++ b/src/test/ui/parser/doc-before-eof.rs @@ -0,0 +1,3 @@ +fn main() {} + +/// hi //~ERROR expected item after doc comment diff --git a/src/test/ui/parser/doc-before-eof.stderr b/src/test/ui/parser/doc-before-eof.stderr new file mode 100644 index 000000000..827566267 --- /dev/null +++ b/src/test/ui/parser/doc-before-eof.stderr @@ -0,0 +1,8 @@ +error: expected item after doc comment + --> $DIR/doc-before-eof.rs:3:1 + | +LL | /// hi + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything + +error: aborting due to previous error + diff --git a/src/test/ui/parser/doc-before-extern-rbrace.rs b/src/test/ui/parser/doc-before-extern-rbrace.rs new file mode 100644 index 000000000..515c90ed4 --- /dev/null +++ b/src/test/ui/parser/doc-before-extern-rbrace.rs @@ -0,0 +1,6 @@ +fn main() {} + +extern "C" { + /// hi + //~^ ERROR found a documentation comment that doesn't document anything +} diff --git a/src/test/ui/parser/doc-before-extern-rbrace.stderr b/src/test/ui/parser/doc-before-extern-rbrace.stderr new file mode 100644 index 000000000..0edceb268 --- /dev/null +++ b/src/test/ui/parser/doc-before-extern-rbrace.stderr @@ -0,0 +1,11 @@ +error[E0584]: found a documentation comment that doesn't document anything + --> $DIR/doc-before-extern-rbrace.rs:4:5 + | +LL | /// hi + | ^^^^^^ this doc comment doesn't document anything + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0584`. diff --git a/src/test/ui/parser/doc-before-fn-rbrace.rs b/src/test/ui/parser/doc-before-fn-rbrace.rs new file mode 100644 index 000000000..eb355136f --- /dev/null +++ b/src/test/ui/parser/doc-before-fn-rbrace.rs @@ -0,0 +1,5 @@ +fn main() { + /// document + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended +} diff --git a/src/test/ui/parser/doc-before-fn-rbrace.stderr b/src/test/ui/parser/doc-before-fn-rbrace.stderr new file mode 100644 index 000000000..56241de70 --- /dev/null +++ b/src/test/ui/parser/doc-before-fn-rbrace.stderr @@ -0,0 +1,11 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-before-fn-rbrace.rs:2:5 + | +LL | /// document + | ^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/doc-before-identifier.rs b/src/test/ui/parser/doc-before-identifier.rs new file mode 100644 index 000000000..76263ad92 --- /dev/null +++ b/src/test/ui/parser/doc-before-identifier.rs @@ -0,0 +1,7 @@ +fn /// document +foo() {} +//~^^ ERROR expected identifier, found doc comment `/// document` + +fn main() { + foo(); +} diff --git a/src/test/ui/parser/doc-before-identifier.stderr b/src/test/ui/parser/doc-before-identifier.stderr new file mode 100644 index 000000000..940d293b6 --- /dev/null +++ b/src/test/ui/parser/doc-before-identifier.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found doc comment `/// document` + --> $DIR/doc-before-identifier.rs:1:4 + | +LL | fn /// document + | ^^^^^^^^^^^^ expected identifier, found doc comment + +error: aborting due to previous error + diff --git a/src/test/ui/parser/doc-before-mod-rbrace.rs b/src/test/ui/parser/doc-before-mod-rbrace.rs new file mode 100644 index 000000000..c65a0a931 --- /dev/null +++ b/src/test/ui/parser/doc-before-mod-rbrace.rs @@ -0,0 +1,6 @@ +mod Foo { + /// document + //~^ ERROR expected item after doc comment +} + +fn main() {} diff --git a/src/test/ui/parser/doc-before-mod-rbrace.stderr b/src/test/ui/parser/doc-before-mod-rbrace.stderr new file mode 100644 index 000000000..d5749c66c --- /dev/null +++ b/src/test/ui/parser/doc-before-mod-rbrace.stderr @@ -0,0 +1,8 @@ +error: expected item after doc comment + --> $DIR/doc-before-mod-rbrace.rs:2:5 + | +LL | /// document + | ^^^^^^^^^^^^ this doc comment doesn't document anything + +error: aborting due to previous error + diff --git a/src/test/ui/parser/doc-before-rbrace.rs b/src/test/ui/parser/doc-before-rbrace.rs new file mode 100644 index 000000000..8ff946344 --- /dev/null +++ b/src/test/ui/parser/doc-before-rbrace.rs @@ -0,0 +1,5 @@ +fn main() { + println!("Hi"); /// hi + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended +} diff --git a/src/test/ui/parser/doc-before-rbrace.stderr b/src/test/ui/parser/doc-before-rbrace.stderr new file mode 100644 index 000000000..55719cf64 --- /dev/null +++ b/src/test/ui/parser/doc-before-rbrace.stderr @@ -0,0 +1,11 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-before-rbrace.rs:2:21 + | +LL | println!("Hi"); /// hi + | ^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/doc-before-semi.rs b/src/test/ui/parser/doc-before-semi.rs new file mode 100644 index 000000000..405a7e1e2 --- /dev/null +++ b/src/test/ui/parser/doc-before-semi.rs @@ -0,0 +1,6 @@ +fn main() { + /// hi + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended + ; +} diff --git a/src/test/ui/parser/doc-before-semi.stderr b/src/test/ui/parser/doc-before-semi.stderr new file mode 100644 index 000000000..e6bade18d --- /dev/null +++ b/src/test/ui/parser/doc-before-semi.stderr @@ -0,0 +1,11 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-before-semi.rs:2:5 + | +LL | /// hi + | ^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.rs b/src/test/ui/parser/doc-before-struct-rbrace-1.rs new file mode 100644 index 000000000..3866a3105 --- /dev/null +++ b/src/test/ui/parser/doc-before-struct-rbrace-1.rs @@ -0,0 +1,10 @@ +struct X { + a: u8, + /// document + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended +} + +fn main() { + let y = X {a: 1}; +} diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr new file mode 100644 index 000000000..19f906773 --- /dev/null +++ b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr @@ -0,0 +1,11 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-before-struct-rbrace-1.rs:3:5 + | +LL | /// document + | ^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.rs b/src/test/ui/parser/doc-before-struct-rbrace-2.rs new file mode 100644 index 000000000..dda138f1a --- /dev/null +++ b/src/test/ui/parser/doc-before-struct-rbrace-2.rs @@ -0,0 +1,9 @@ +struct X { + a: u8 /// document + //~^ ERROR found a documentation comment that doesn't document anything + //~| HELP maybe a comment was intended +} + +fn main() { + let y = X {a: 1}; +} diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.stderr b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr new file mode 100644 index 000000000..b25ccab79 --- /dev/null +++ b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr @@ -0,0 +1,11 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/doc-before-struct-rbrace-2.rs:2:11 + | +LL | a: u8 /// document + | ^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/doc-comment-in-if-statement.rs b/src/test/ui/parser/doc-comment-in-if-statement.rs new file mode 100644 index 000000000..343eac1b8 --- /dev/null +++ b/src/test/ui/parser/doc-comment-in-if-statement.rs @@ -0,0 +1,5 @@ +fn main() { + if true /*!*/ {} + //~^ ERROR outer attributes are not allowed on + //~| ERROR expected outer doc comment +} diff --git a/src/test/ui/parser/doc-comment-in-if-statement.stderr b/src/test/ui/parser/doc-comment-in-if-statement.stderr new file mode 100644 index 000000000..fc0bc5073 --- /dev/null +++ b/src/test/ui/parser/doc-comment-in-if-statement.stderr @@ -0,0 +1,25 @@ +error[E0753]: expected outer doc comment + --> $DIR/doc-comment-in-if-statement.rs:2:13 + | +LL | if true /*!*/ {} + | ^^^^^ + | + = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - if true /*!*/ {} +LL + if true /**/ {} + | + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/doc-comment-in-if-statement.rs:2:13 + | +LL | if true /*!*/ {} + | -- ^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0753`. diff --git a/src/test/ui/parser/doc-comment-in-stmt.rs b/src/test/ui/parser/doc-comment-in-stmt.rs new file mode 100644 index 000000000..b02df1321 --- /dev/null +++ b/src/test/ui/parser/doc-comment-in-stmt.rs @@ -0,0 +1,20 @@ +fn foo() -> bool { + false + //!self.allow_ty_infer() + //~^ ERROR found doc comment +} + +fn bar() -> bool { + false + /*! bar */ //~ ERROR found doc comment +} + +fn baz() -> i32 { + 1 /** baz */ //~ ERROR found doc comment +} + +fn quux() -> i32 { + 2 /*! quux */ //~ ERROR found doc comment +} + +fn main() {} diff --git a/src/test/ui/parser/doc-comment-in-stmt.stderr b/src/test/ui/parser/doc-comment-in-stmt.stderr new file mode 100644 index 000000000..febfb600c --- /dev/null +++ b/src/test/ui/parser/doc-comment-in-stmt.stderr @@ -0,0 +1,50 @@ +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `//!self.allow_ty_infer()` + --> $DIR/doc-comment-in-stmt.rs:3:5 + | +LL | false + | - expected one of `.`, `;`, `?`, `}`, or an operator +LL | //!self.allow_ty_infer() + | ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected token + | +help: add a space before `!` to use a regular comment + | +LL | // !self.allow_ty_infer() + | ~~~~ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! bar */` + --> $DIR/doc-comment-in-stmt.rs:9:5 + | +LL | false + | - expected one of `.`, `;`, `?`, `}`, or an operator +LL | /*! bar */ + | ^^^^^^^^^^ unexpected token + | +help: add a space before `!` to use a regular comment + | +LL | /* ! bar */ + | ~~~~ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/** baz */` + --> $DIR/doc-comment-in-stmt.rs:13:7 + | +LL | 1 /** baz */ + | ^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + | +help: add a space before `*` to use a regular comment + | +LL | 1 /* * baz */ + | ~~~~ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! quux */` + --> $DIR/doc-comment-in-stmt.rs:17:7 + | +LL | 2 /*! quux */ + | ^^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + | +help: add a space before `!` to use a regular comment + | +LL | 2 /* ! quux */ + | ~~~~ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/doc-inside-trait-item.rs b/src/test/ui/parser/doc-inside-trait-item.rs new file mode 100644 index 000000000..87b501bd2 --- /dev/null +++ b/src/test/ui/parser/doc-inside-trait-item.rs @@ -0,0 +1,6 @@ +trait User{ + fn test(); + /// empty doc + //~^ ERROR found a documentation comment that doesn't document anything +} +fn main() {} diff --git a/src/test/ui/parser/doc-inside-trait-item.stderr b/src/test/ui/parser/doc-inside-trait-item.stderr new file mode 100644 index 000000000..246255a0a --- /dev/null +++ b/src/test/ui/parser/doc-inside-trait-item.stderr @@ -0,0 +1,11 @@ +error[E0584]: found a documentation comment that doesn't document anything + --> $DIR/doc-inside-trait-item.rs:3:5 + | +LL | /// empty doc + | ^^^^^^^^^^^^^ this doc comment doesn't document anything + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0584`. diff --git a/src/test/ui/parser/dotdotdot-expr.rs b/src/test/ui/parser/dotdotdot-expr.rs new file mode 100644 index 000000000..d842fb6e0 --- /dev/null +++ b/src/test/ui/parser/dotdotdot-expr.rs @@ -0,0 +1,4 @@ +fn main() { + let _redemptive = 1...21; + //~^ ERROR unexpected token +} diff --git a/src/test/ui/parser/dotdotdot-expr.stderr b/src/test/ui/parser/dotdotdot-expr.stderr new file mode 100644 index 000000000..e7203f24d --- /dev/null +++ b/src/test/ui/parser/dotdotdot-expr.stderr @@ -0,0 +1,17 @@ +error: unexpected token: `...` + --> $DIR/dotdotdot-expr.rs:2:24 + | +LL | let _redemptive = 1...21; + | ^^^ + | +help: use `..` for an exclusive range + | +LL | let _redemptive = 1..21; + | ~~ +help: or `..=` for an inclusive range + | +LL | let _redemptive = 1..=21; + | ~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs new file mode 100644 index 000000000..54955944c --- /dev/null +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -0,0 +1,9 @@ +fn main() {} + +extern "C" { //~ NOTE while parsing this item list starting here + pub pub fn foo(); + //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub` + //~| NOTE expected one of 8 possible tokens + //~| HELP there is already a visibility modifier, remove one + //~| NOTE explicit visibility first seen here +} //~ NOTE the item list ends here diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr new file mode 100644 index 000000000..8ecebf01f --- /dev/null +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -0,0 +1,22 @@ +error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub` + --> $DIR/duplicate-visibility.rs:4:9 + | +LL | extern "C" { + | - while parsing this item list starting here +LL | pub pub fn foo(); + | ^^^ + | | + | expected one of 8 possible tokens + | help: there is already a visibility modifier, remove one +... +LL | } + | - the item list ends here + | +note: explicit visibility first seen here + --> $DIR/duplicate-visibility.rs:4:5 + | +LL | pub pub fn foo(); + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/duplicate-where-clauses.rs b/src/test/ui/parser/duplicate-where-clauses.rs new file mode 100644 index 000000000..9eb2ffb06 --- /dev/null +++ b/src/test/ui/parser/duplicate-where-clauses.rs @@ -0,0 +1,19 @@ +struct A where (): Sized where (): Sized {} +//~^ ERROR cannot define duplicate `where` clauses on an item + +fn b() where (): Sized where (): Sized {} +//~^ ERROR cannot define duplicate `where` clauses on an item + +enum C where (): Sized where (): Sized {} +//~^ ERROR cannot define duplicate `where` clauses on an item + +struct D where (): Sized, where (): Sized {} +//~^ ERROR cannot define duplicate `where` clauses on an item + +fn e() where (): Sized, where (): Sized {} +//~^ ERROR cannot define duplicate `where` clauses on an item + +enum F where (): Sized, where (): Sized {} +//~^ ERROR cannot define duplicate `where` clauses on an item + +fn main() {} diff --git a/src/test/ui/parser/duplicate-where-clauses.stderr b/src/test/ui/parser/duplicate-where-clauses.stderr new file mode 100644 index 000000000..8250d4f1e --- /dev/null +++ b/src/test/ui/parser/duplicate-where-clauses.stderr @@ -0,0 +1,80 @@ +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:1:32 + | +LL | struct A where (): Sized where (): Sized {} + | - ^ + | | + | previous `where` clause starts here + | +help: consider joining the two `where` clauses into one + | +LL | struct A where (): Sized, (): Sized {} + | ~ + +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:4:30 + | +LL | fn b() where (): Sized where (): Sized {} + | - ^ + | | + | previous `where` clause starts here + | +help: consider joining the two `where` clauses into one + | +LL | fn b() where (): Sized, (): Sized {} + | ~ + +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:7:30 + | +LL | enum C where (): Sized where (): Sized {} + | - ^ + | | + | previous `where` clause starts here + | +help: consider joining the two `where` clauses into one + | +LL | enum C where (): Sized, (): Sized {} + | ~ + +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:10:33 + | +LL | struct D where (): Sized, where (): Sized {} + | - ^ + | | + | previous `where` clause starts here + | +help: consider joining the two `where` clauses into one + | +LL | struct D where (): Sized, (): Sized {} + | ~ + +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:13:31 + | +LL | fn e() where (): Sized, where (): Sized {} + | - ^ + | | + | previous `where` clause starts here + | +help: consider joining the two `where` clauses into one + | +LL | fn e() where (): Sized, (): Sized {} + | ~ + +error: cannot define duplicate `where` clauses on an item + --> $DIR/duplicate-where-clauses.rs:16:31 + | +LL | enum F where (): Sized, where (): Sized {} + | - ^ + | | + | previous `where` clause starts here + | +help: consider joining the two `where` clauses into one + | +LL | enum F where (): Sized, (): Sized {} + | ~ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/dyn-trait-compatibility.rs b/src/test/ui/parser/dyn-trait-compatibility.rs new file mode 100644 index 000000000..d2b02cc2a --- /dev/null +++ b/src/test/ui/parser/dyn-trait-compatibility.rs @@ -0,0 +1,14 @@ +type A0 = dyn; +//~^ ERROR cannot find type `dyn` in this scope +type A1 = dyn::dyn; +//~^ ERROR use of undeclared crate or module `dyn` +type A2 = dyn<dyn, dyn>; +//~^ ERROR cannot find type `dyn` in this scope +//~| ERROR cannot find type `dyn` in this scope +//~| ERROR cannot find type `dyn` in this scope +type A3 = dyn<<dyn as dyn>::dyn>; +//~^ ERROR cannot find type `dyn` in this scope +//~| ERROR cannot find type `dyn` in this scope +//~| ERROR use of undeclared crate or module `dyn` + +fn main() {} diff --git a/src/test/ui/parser/dyn-trait-compatibility.stderr b/src/test/ui/parser/dyn-trait-compatibility.stderr new file mode 100644 index 000000000..9218ae9d5 --- /dev/null +++ b/src/test/ui/parser/dyn-trait-compatibility.stderr @@ -0,0 +1,58 @@ +error[E0433]: failed to resolve: use of undeclared crate or module `dyn` + --> $DIR/dyn-trait-compatibility.rs:3:11 + | +LL | type A1 = dyn::dyn; + | ^^^ use of undeclared crate or module `dyn` + +error[E0433]: failed to resolve: use of undeclared crate or module `dyn` + --> $DIR/dyn-trait-compatibility.rs:9:23 + | +LL | type A3 = dyn<<dyn as dyn>::dyn>; + | ^^^ use of undeclared crate or module `dyn` + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/dyn-trait-compatibility.rs:1:11 + | +LL | type A0 = dyn; + | ^^^ not found in this scope + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/dyn-trait-compatibility.rs:5:11 + | +LL | type A2 = dyn<dyn, dyn>; + | ^^^ not found in this scope + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/dyn-trait-compatibility.rs:5:15 + | +LL | type A2 = dyn<dyn, dyn>; + | - ^^^ not found in this scope + | | + | help: you might be missing a type parameter: `<dyn>` + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/dyn-trait-compatibility.rs:5:20 + | +LL | type A2 = dyn<dyn, dyn>; + | - ^^^ not found in this scope + | | + | help: you might be missing a type parameter: `<dyn>` + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/dyn-trait-compatibility.rs:9:11 + | +LL | type A3 = dyn<<dyn as dyn>::dyn>; + | ^^^ not found in this scope + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/dyn-trait-compatibility.rs:9:16 + | +LL | type A3 = dyn<<dyn as dyn>::dyn>; + | - ^^^ not found in this scope + | | + | help: you might be missing a type parameter: `<dyn>` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0412, E0433. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/parser/else-no-if.rs b/src/test/ui/parser/else-no-if.rs new file mode 100644 index 000000000..f0b40ecde --- /dev/null +++ b/src/test/ui/parser/else-no-if.rs @@ -0,0 +1,32 @@ +fn foo() { + if true { + } else false { + //~^ ERROR expected `{`, found keyword `false` + } +} + +fn foo2() { + if true { + } else falsy() { + //~^ ERROR expected `{`, found `falsy` + } +} + +fn foo3() { + if true { + } else falsy(); + //~^ ERROR expected `{`, found `falsy` +} + +fn foo4() { + if true { + } else loop{} + //~^ ERROR expected `{`, found keyword `loop` + {} +} + +fn falsy() -> bool { + false +} + +fn main() {} diff --git a/src/test/ui/parser/else-no-if.stderr b/src/test/ui/parser/else-no-if.stderr new file mode 100644 index 000000000..b9c1a7527 --- /dev/null +++ b/src/test/ui/parser/else-no-if.stderr @@ -0,0 +1,50 @@ +error: expected `{`, found keyword `false` + --> $DIR/else-no-if.rs:3:12 + | +LL | } else false { + | ---- ^^^^^ + | | + | expected an `if` or a block after this `else` + | +help: add an `if` if this is the condition of a chained `else if` statement + | +LL | } else if false { + | ++ + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:10:12 + | +LL | } else falsy() { + | ---- ^^^^^ + | | + | expected an `if` or a block after this `else` + | +help: add an `if` if this is the condition of a chained `else if` statement + | +LL | } else if falsy() { + | ++ + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:17:12 + | +LL | } else falsy(); + | ^^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { falsy() }; + | + + + +error: expected `{`, found keyword `loop` + --> $DIR/else-no-if.rs:23:12 + | +LL | } else loop{} + | ^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { loop{} } + | + + + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/emoji-identifiers.rs b/src/test/ui/parser/emoji-identifiers.rs new file mode 100644 index 000000000..b50c046bc --- /dev/null +++ b/src/test/ui/parser/emoji-identifiers.rs @@ -0,0 +1,19 @@ +struct ABig👩👩👧👧Family; //~ ERROR identifiers cannot contain emoji +struct 👀; //~ ERROR identifiers cannot contain emoji +impl 👀 { + fn full_of_✨() -> 👀 { //~ ERROR identifiers cannot contain emoji + 👀 + } +} +fn i_like_to_😅_a_lot() -> 👀 { //~ ERROR identifiers cannot contain emoji + 👀::full_of✨() //~ ERROR no function or associated item named `full_of✨` found for struct `👀` + //~^ ERROR identifiers cannot contain emoji +} +fn main() { + let _ = i_like_to_😄_a_lot() ➖ 4; //~ ERROR cannot find function `i_like_to_😄_a_lot` in this scope + //~^ ERROR identifiers cannot contain emoji + //~| ERROR unknown start of token: \u{2796} + + let 🦀 = 1;//~ ERROR Ferris cannot be used as an identifier + dbg!(🦀); +} diff --git a/src/test/ui/parser/emoji-identifiers.stderr b/src/test/ui/parser/emoji-identifiers.stderr new file mode 100644 index 000000000..2550dc3d3 --- /dev/null +++ b/src/test/ui/parser/emoji-identifiers.stderr @@ -0,0 +1,91 @@ +error: unknown start of token: \u{2796} + --> $DIR/emoji-identifiers.rs:13:33 + | +LL | let _ = i_like_to_😄_a_lot() ➖ 4; + | ^^ + | +help: Unicode character '➖' (Heavy Minus Sign) looks like '-' (Minus/Hyphen), but it is not + | +LL | let _ = i_like_to_😄_a_lot() - 4; + | ~ + +error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope + --> $DIR/emoji-identifiers.rs:13:13 + | +LL | fn i_like_to_😅_a_lot() -> 👀 { + | ----------------------------- similarly named function `i_like_to_😅_a_lot` defined here +... +LL | let _ = i_like_to_😄_a_lot() ➖ 4; + | ^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `i_like_to_😅_a_lot` + +error: Ferris cannot be used as an identifier + --> $DIR/emoji-identifiers.rs:17:9 + | +LL | let 🦀 = 1; + | ^^ help: try using their name instead: `ferris` +LL | dbg!(🦀); + | ^^ + +error: identifiers cannot contain emoji: `ABig👩👩👧👧Family` + --> $DIR/emoji-identifiers.rs:1:8 + | +LL | struct ABig👩👩👧👧Family; + | ^^^^^^^^^^^^^^^^^^ + +error: identifiers cannot contain emoji: `👀` + --> $DIR/emoji-identifiers.rs:2:8 + | +LL | struct 👀; + | ^^ +LL | impl 👀 { + | ^^ +LL | fn full_of_✨() -> 👀 { + | ^^ +LL | 👀 + | ^^ +... +LL | fn i_like_to_😅_a_lot() -> 👀 { + | ^^ +LL | 👀::full_of✨() + | ^^ + +error: identifiers cannot contain emoji: `full_of_✨` + --> $DIR/emoji-identifiers.rs:4:8 + | +LL | fn full_of_✨() -> 👀 { + | ^^^^^^^^^^ + +error: identifiers cannot contain emoji: `i_like_to_😅_a_lot` + --> $DIR/emoji-identifiers.rs:8:4 + | +LL | fn i_like_to_😅_a_lot() -> 👀 { + | ^^^^^^^^^^^^^^^^^^ + +error: identifiers cannot contain emoji: `full_of✨` + --> $DIR/emoji-identifiers.rs:9:8 + | +LL | 👀::full_of✨() + | ^^^^^^^^^ + +error: identifiers cannot contain emoji: `i_like_to_😄_a_lot` + --> $DIR/emoji-identifiers.rs:13:13 + | +LL | let _ = i_like_to_😄_a_lot() ➖ 4; + | ^^^^^^^^^^^^^^^^^^ + +error[E0599]: no function or associated item named `full_of✨` found for struct `👀` in the current scope + --> $DIR/emoji-identifiers.rs:9:8 + | +LL | struct 👀; + | --------- function or associated item `full_of✨` not found for this struct +... +LL | 👀::full_of✨() + | ^^^^^^^^^ + | | + | function or associated item not found in `👀` + | help: there is an associated function with a similar name: `full_of_✨` + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0425, E0599. +For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/empty-impl-semicolon.rs b/src/test/ui/parser/empty-impl-semicolon.rs new file mode 100644 index 000000000..207ebef64 --- /dev/null +++ b/src/test/ui/parser/empty-impl-semicolon.rs @@ -0,0 +1 @@ +impl Foo; //~ ERROR expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;` diff --git a/src/test/ui/parser/empty-impl-semicolon.stderr b/src/test/ui/parser/empty-impl-semicolon.stderr new file mode 100644 index 000000000..398eb5c89 --- /dev/null +++ b/src/test/ui/parser/empty-impl-semicolon.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;` + --> $DIR/empty-impl-semicolon.rs:1:9 + | +LL | impl Foo; + | ^ expected one of 8 possible tokens + +error: aborting due to previous error + diff --git a/src/test/ui/parser/expr-as-stmt-2.rs b/src/test/ui/parser/expr-as-stmt-2.rs new file mode 100644 index 000000000..3a18bdc3b --- /dev/null +++ b/src/test/ui/parser/expr-as-stmt-2.rs @@ -0,0 +1,10 @@ +// This is not autofixable because we give extra suggestions to end the first expression with `;`. +fn foo(a: Option<u32>, b: Option<u32>) -> bool { + if let Some(x) = a { true } else { false } + //~^ ERROR mismatched types + //~| ERROR mismatched types + && //~ ERROR mismatched types + if let Some(y) = a { true } else { false } +} + +fn main() {} diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr new file mode 100644 index 000000000..9b939f05e --- /dev/null +++ b/src/test/ui/parser/expr-as-stmt-2.stderr @@ -0,0 +1,51 @@ +error[E0308]: mismatched types + --> $DIR/expr-as-stmt-2.rs:3:26 + | +LL | if let Some(x) = a { true } else { false } + | ---------------------^^^^----------------- + | | | + | | expected `()`, found `bool` + | expected this to be `()` + | +help: you might have meant to return this value + | +LL | if let Some(x) = a { return true; } else { false } + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt-2.rs:3:40 + | +LL | if let Some(x) = a { true } else { false } + | -----------------------------------^^^^^-- + | | | + | | expected `()`, found `bool` + | expected this to be `()` + | +help: you might have meant to return this value + | +LL | if let Some(x) = a { true } else { return false; } + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt-2.rs:6:5 + | +LL | fn foo(a: Option<u32>, b: Option<u32>) -> bool { + | ---- expected `bool` because of return type +... +LL | / && +LL | | if let Some(y) = a { true } else { false } + | |______________________________________________^ expected `bool`, found `&&bool` + | +help: consider removing the `&&` + | +LL - && +LL + if let Some(y) = a { true } else { false } + | +help: parentheses are required to parse this as an expression + | +LL | (if let Some(x) = a { true } else { false }) + | + + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed new file mode 100644 index 000000000..36709eea1 --- /dev/null +++ b/src/test/ui/parser/expr-as-stmt.fixed @@ -0,0 +1,67 @@ +// run-rustfix +// rustfix-only-machine-applicable +#![allow(unused_variables)] +#![allow(dead_code)] +#![allow(unused_must_use)] + +fn foo() -> i32 { + ({2}) + {2} //~ ERROR expected expression, found `+` + //~^ ERROR mismatched types +} + +fn bar() -> i32 { + ({2}) + 2 //~ ERROR leading `+` is not supported + //~^ ERROR mismatched types +} + +fn zul() -> u32 { + let foo = 3; + ({ 42 }) + foo; //~ ERROR expected expression, found `+` + //~^ ERROR mismatched types + 32 +} + +fn baz() -> i32 { + ({ 3 }) * 3 //~ ERROR type `{integer}` cannot be dereferenced + //~^ ERROR mismatched types +} + +fn moo(x: u32) -> bool { + (match x { + _ => 1, + }) > 0 //~ ERROR expected expression +} + +fn qux() -> u32 { + ({2}) - 2 //~ ERROR cannot apply unary operator `-` to type `u32` + //~^ ERROR mismatched types +} + +fn space_cadet() -> bool { + ({ true }) | { true } //~ ERROR E0308 + //~^ ERROR expected parameter name +} + +fn revenge_from_mars() -> bool { + ({ true }) && { true } //~ ERROR E0308 + //~^ ERROR mismatched types +} + +fn attack_from_mars() -> bool { + ({ true }) || { true } //~ ERROR E0308 + //~^ ERROR mismatched types +} + +// This gets corrected by adding a semicolon, instead of parens. +// It's placed here to help keep track of the way this diagnostic +// needs to interact with type checking to avoid MachineApplicable +// suggestions that actually break stuff. +// +// If you're wondering what happens if that `foo()` is a `true` like +// all the ones above use? Nothing. It makes neither suggestion in +// that case. +fn asteroids() -> impl FnOnce() -> bool { + { foo(); } || { true } //~ ERROR E0308 +} + +fn main() {} diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs new file mode 100644 index 000000000..92bb972b2 --- /dev/null +++ b/src/test/ui/parser/expr-as-stmt.rs @@ -0,0 +1,67 @@ +// run-rustfix +// rustfix-only-machine-applicable +#![allow(unused_variables)] +#![allow(dead_code)] +#![allow(unused_must_use)] + +fn foo() -> i32 { + {2} + {2} //~ ERROR expected expression, found `+` + //~^ ERROR mismatched types +} + +fn bar() -> i32 { + {2} + 2 //~ ERROR leading `+` is not supported + //~^ ERROR mismatched types +} + +fn zul() -> u32 { + let foo = 3; + { 42 } + foo; //~ ERROR expected expression, found `+` + //~^ ERROR mismatched types + 32 +} + +fn baz() -> i32 { + { 3 } * 3 //~ ERROR type `{integer}` cannot be dereferenced + //~^ ERROR mismatched types +} + +fn moo(x: u32) -> bool { + match x { + _ => 1, + } > 0 //~ ERROR expected expression +} + +fn qux() -> u32 { + {2} - 2 //~ ERROR cannot apply unary operator `-` to type `u32` + //~^ ERROR mismatched types +} + +fn space_cadet() -> bool { + { true } | { true } //~ ERROR E0308 + //~^ ERROR expected parameter name +} + +fn revenge_from_mars() -> bool { + { true } && { true } //~ ERROR E0308 + //~^ ERROR mismatched types +} + +fn attack_from_mars() -> bool { + { true } || { true } //~ ERROR E0308 + //~^ ERROR mismatched types +} + +// This gets corrected by adding a semicolon, instead of parens. +// It's placed here to help keep track of the way this diagnostic +// needs to interact with type checking to avoid MachineApplicable +// suggestions that actually break stuff. +// +// If you're wondering what happens if that `foo()` is a `true` like +// all the ones above use? Nothing. It makes neither suggestion in +// that case. +fn asteroids() -> impl FnOnce() -> bool { + { foo() } || { true } //~ ERROR E0308 +} + +fn main() {} diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr new file mode 100644 index 000000000..858b4e8db --- /dev/null +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -0,0 +1,216 @@ +error: expected expression, found `+` + --> $DIR/expr-as-stmt.rs:8:9 + | +LL | {2} + {2} + | ^ expected expression + | +help: parentheses are required to parse this as an expression + | +LL | ({2}) + {2} + | + + + +error: leading `+` is not supported + --> $DIR/expr-as-stmt.rs:13:9 + | +LL | {2} + 2 + | ^ unexpected `+` + | +help: parentheses are required to parse this as an expression + | +LL | ({2}) + 2 + | + + + +error: expected expression, found `+` + --> $DIR/expr-as-stmt.rs:19:12 + | +LL | { 42 } + foo; + | ^ expected expression + | +help: parentheses are required to parse this as an expression + | +LL | ({ 42 }) + foo; + | + + + +error: expected expression, found `>` + --> $DIR/expr-as-stmt.rs:32:7 + | +LL | } > 0 + | ^ expected expression + | +help: parentheses are required to parse this as an expression + | +LL ~ (match x { +LL | _ => 1, +LL ~ }) > 0 + | + +error: expected parameter name, found `{` + --> $DIR/expr-as-stmt.rs:41:16 + | +LL | { true } | { true } + | ^ expected parameter name + | +help: parentheses are required to parse this as an expression + | +LL | ({ true }) | { true } + | + + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:64:7 + | +LL | { foo() } || { true } + | ^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:8:6 + | +LL | {2} + {2} + | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | {return 2;} + {2} + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:13:6 + | +LL | {2} + 2 + | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | {return 2;} + 2 + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:19:7 + | +LL | { 42 } + foo; + | ^^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | { return 42; } + foo; + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:25:7 + | +LL | { 3 } * 3 + | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | { return 3; } * 3 + | ++++++ + + +error[E0614]: type `{integer}` cannot be dereferenced + --> $DIR/expr-as-stmt.rs:25:11 + | +LL | { 3 } * 3 + | ^^^ + | +help: parentheses are required to parse this as an expression + | +LL | ({ 3 }) * 3 + | + + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:36:6 + | +LL | {2} - 2 + | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | {return 2;} - 2 + | ++++++ + + +error[E0600]: cannot apply unary operator `-` to type `u32` + --> $DIR/expr-as-stmt.rs:36:9 + | +LL | {2} - 2 + | ^^^ cannot apply unary operator `-` + | +help: parentheses are required to parse this as an expression + | +LL | ({2}) - 2 + | + + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:41:7 + | +LL | { true } | { true } + | ^^^^ expected `()`, found `bool` + | +help: you might have meant to return this value + | +LL | { return true; } | { true } + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:46:7 + | +LL | { true } && { true } + | ^^^^ expected `()`, found `bool` + | +help: you might have meant to return this value + | +LL | { return true; } && { true } + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:46:14 + | +LL | fn revenge_from_mars() -> bool { + | ---- expected `bool` because of return type +LL | { true } && { true } + | ^^^^^^^^^^^ expected `bool`, found `&&bool` + | +help: consider removing the `&&` + | +LL - { true } && { true } +LL + { true } { true } + | +help: parentheses are required to parse this as an expression + | +LL | ({ true }) && { true } + | + + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:51:7 + | +LL | { true } || { true } + | ^^^^ expected `()`, found `bool` + | +help: you might have meant to return this value + | +LL | { return true; } || { true } + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/expr-as-stmt.rs:51:14 + | +LL | fn attack_from_mars() -> bool { + | ---- expected `bool` because of return type +LL | { true } || { true } + | ^^^^^^^^^^^ expected `bool`, found closure + | + = note: expected type `bool` + found closure `[closure@$DIR/expr-as-stmt.rs:51:14: 51:16]` +help: use parentheses to call this closure + | +LL | { true } (|| { true })() + | + +++ +help: parentheses are required to parse this as an expression + | +LL | ({ true }) || { true } + | + + + +error: aborting due to 18 previous errors + +Some errors have detailed explanations: E0308, E0600, E0614. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs new file mode 100644 index 000000000..8f5d7f4f7 --- /dev/null +++ b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs @@ -0,0 +1,47 @@ +#![allow(clashing_extern_declarations)] +// check-pass + +// In this test we check that the parser accepts an ABI string when it +// comes from a macro `literal` or `expr` fragment as opposed to a hardcoded string. + +fn main() {} + +macro_rules! abi_from_lit_frag { + ($abi:literal) => { + extern $abi { + fn _import(); + } + + extern $abi fn _export() {} + + type _PTR = extern $abi fn(); + } +} + +macro_rules! abi_from_expr_frag { + ($abi:expr) => { + extern $abi { + fn _import(); + } + + extern $abi fn _export() {} + + type _PTR = extern $abi fn(); + }; +} + +mod rust { + abi_from_lit_frag!("Rust"); +} + +mod c { + abi_from_lit_frag!("C"); +} + +mod rust_expr { + abi_from_expr_frag!("Rust"); +} + +mod c_expr { + abi_from_expr_frag!("C"); +} diff --git a/src/test/ui/parser/extern-abi-raw-strings.rs b/src/test/ui/parser/extern-abi-raw-strings.rs new file mode 100644 index 000000000..fad855a21 --- /dev/null +++ b/src/test/ui/parser/extern-abi-raw-strings.rs @@ -0,0 +1,13 @@ +// check-pass + +// Check that the string literal in `extern lit` will accept raw strings. + +fn main() {} + +extern r#"C"# fn foo() {} + +extern r#"C"# { + fn bar(); +} + +type T = extern r#"C"# fn(); diff --git a/src/test/ui/parser/extern-abi-string-escaping.rs b/src/test/ui/parser/extern-abi-string-escaping.rs new file mode 100644 index 000000000..87bd31aab --- /dev/null +++ b/src/test/ui/parser/extern-abi-string-escaping.rs @@ -0,0 +1,13 @@ +// check-pass + +// Check that the string literal in `extern lit` will escapes. + +fn main() {} + +extern "\x43" fn foo() {} + +extern "\x43" { + fn bar(); +} + +type T = extern "\x43" fn(); diff --git a/src/test/ui/parser/extern-abi-syntactic.rs b/src/test/ui/parser/extern-abi-syntactic.rs new file mode 100644 index 000000000..7d2bbfe8a --- /dev/null +++ b/src/test/ui/parser/extern-abi-syntactic.rs @@ -0,0 +1,17 @@ +// check-pass + +// Check that from the grammar's point of view, +// the specific set of ABIs is not part of it. + +fn main() {} + +#[cfg(FALSE)] +extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn foo() {} + +#[cfg(FALSE)] +extern "some_abi_that_we_are_sure_does_not_exist_semantically" { + fn foo(); +} + +#[cfg(FALSE)] +type T = extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn(); diff --git a/src/test/ui/parser/extern-crate-async.rs b/src/test/ui/parser/extern-crate-async.rs new file mode 100644 index 000000000..6a54ac7f4 --- /dev/null +++ b/src/test/ui/parser/extern-crate-async.rs @@ -0,0 +1,12 @@ +// Make sure that we don't parse `extern crate async` +// the front matter of a function leading us astray. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +extern crate async; + +#[cfg(FALSE)] +extern crate async as something_else; diff --git a/src/test/ui/parser/extern-crate-unexpected-token.rs b/src/test/ui/parser/extern-crate-unexpected-token.rs new file mode 100644 index 000000000..7687f5e64 --- /dev/null +++ b/src/test/ui/parser/extern-crate-unexpected-token.rs @@ -0,0 +1 @@ +extern crte foo; //~ ERROR expected one of `crate` or `{`, found `crte` diff --git a/src/test/ui/parser/extern-crate-unexpected-token.stderr b/src/test/ui/parser/extern-crate-unexpected-token.stderr new file mode 100644 index 000000000..e9d287ac0 --- /dev/null +++ b/src/test/ui/parser/extern-crate-unexpected-token.stderr @@ -0,0 +1,8 @@ +error: expected one of `crate` or `{`, found `crte` + --> $DIR/extern-crate-unexpected-token.rs:1:8 + | +LL | extern crte foo; + | ^^^^ expected one of `crate` or `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/extern-expected-fn-or-brace.rs b/src/test/ui/parser/extern-expected-fn-or-brace.rs new file mode 100644 index 000000000..1dcea1744 --- /dev/null +++ b/src/test/ui/parser/extern-expected-fn-or-brace.rs @@ -0,0 +1,3 @@ +// Verifies that the expected token errors for `extern crate` are raised. + +extern "C" mod foo; //~ERROR expected `{`, found keyword `mod` diff --git a/src/test/ui/parser/extern-expected-fn-or-brace.stderr b/src/test/ui/parser/extern-expected-fn-or-brace.stderr new file mode 100644 index 000000000..258a2c268 --- /dev/null +++ b/src/test/ui/parser/extern-expected-fn-or-brace.stderr @@ -0,0 +1,8 @@ +error: expected `{`, found keyword `mod` + --> $DIR/extern-expected-fn-or-brace.rs:3:12 + | +LL | extern "C" mod foo; + | ^^^ expected `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/extern-foreign-crate.rs b/src/test/ui/parser/extern-foreign-crate.rs new file mode 100644 index 000000000..a5da77dc7 --- /dev/null +++ b/src/test/ui/parser/extern-foreign-crate.rs @@ -0,0 +1,4 @@ +// Verifies that the expected token errors for `extern crate` are +// raised + +extern crate foo {} //~ERROR expected one of `;` or `as`, found `{` diff --git a/src/test/ui/parser/extern-foreign-crate.stderr b/src/test/ui/parser/extern-foreign-crate.stderr new file mode 100644 index 000000000..eb75c0fc9 --- /dev/null +++ b/src/test/ui/parser/extern-foreign-crate.stderr @@ -0,0 +1,8 @@ +error: expected one of `;` or `as`, found `{` + --> $DIR/extern-foreign-crate.rs:4:18 + | +LL | extern crate foo {} + | ^ expected one of `;` or `as` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/extern-no-fn.rs b/src/test/ui/parser/extern-no-fn.rs new file mode 100644 index 000000000..73568609c --- /dev/null +++ b/src/test/ui/parser/extern-no-fn.rs @@ -0,0 +1,6 @@ +extern "C" { + f(); //~ ERROR expected one of `!` or `::`, found `(` +} + +fn main() { +} diff --git a/src/test/ui/parser/extern-no-fn.stderr b/src/test/ui/parser/extern-no-fn.stderr new file mode 100644 index 000000000..d9183d564 --- /dev/null +++ b/src/test/ui/parser/extern-no-fn.stderr @@ -0,0 +1,12 @@ +error: expected one of `!` or `::`, found `(` + --> $DIR/extern-no-fn.rs:2:6 + | +LL | extern "C" { + | - while parsing this item list starting here +LL | f(); + | ^ expected one of `!` or `::` +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/float-field-interpolated.rs b/src/test/ui/parser/float-field-interpolated.rs new file mode 100644 index 000000000..a30532035 --- /dev/null +++ b/src/test/ui/parser/float-field-interpolated.rs @@ -0,0 +1,17 @@ +struct S(u8, (u8, u8)); + +macro_rules! generate_field_accesses { + ($a:tt, $b:literal, $c:expr) => { + let s = S(0, (0, 0)); + + s.$a; // OK + { s.$b; } //~ ERROR unexpected token: `1.1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1` + { s.$c; } //~ ERROR unexpected token: `1.1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1` + }; +} + +fn main() { + generate_field_accesses!(1.1, 1.1, 1.1); +} diff --git a/src/test/ui/parser/float-field-interpolated.stderr b/src/test/ui/parser/float-field-interpolated.stderr new file mode 100644 index 000000000..664adb358 --- /dev/null +++ b/src/test/ui/parser/float-field-interpolated.stderr @@ -0,0 +1,46 @@ +error: unexpected token: `1.1` + --> $DIR/float-field-interpolated.rs:8:13 + | +LL | { s.$b; } + | ^^ +... +LL | generate_field_accesses!(1.1, 1.1, 1.1); + | --------------------------------------- in this macro invocation + | + = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1` + --> $DIR/float-field-interpolated.rs:8:13 + | +LL | { s.$b; } + | ^^ expected one of `.`, `;`, `?`, `}`, or an operator +... +LL | generate_field_accesses!(1.1, 1.1, 1.1); + | --------------------------------------- in this macro invocation + | + = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unexpected token: `1.1` + --> $DIR/float-field-interpolated.rs:10:13 + | +LL | { s.$c; } + | ^^ +... +LL | generate_field_accesses!(1.1, 1.1, 1.1); + | --------------------------------------- in this macro invocation + | + = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1` + --> $DIR/float-field-interpolated.rs:10:13 + | +LL | { s.$c; } + | ^^ expected one of `.`, `;`, `?`, `}`, or an operator +... +LL | generate_field_accesses!(1.1, 1.1, 1.1); + | --------------------------------------- in this macro invocation + | + = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/float-field.rs b/src/test/ui/parser/float-field.rs new file mode 100644 index 000000000..eaa7465dc --- /dev/null +++ b/src/test/ui/parser/float-field.rs @@ -0,0 +1,62 @@ +struct S(u8, (u8, u8)); + +fn main() { + let s = S(0, (0, 0)); + + s.1e1; //~ ERROR no field `1e1` on type `S` + s.1.; //~ ERROR unexpected token: `;` + s.1.1; + s.1.1e1; //~ ERROR no field `1e1` on type `(u8, u8)` + { s.1e+; } //~ ERROR unexpected token: `1e+` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+` + //~| ERROR expected at least one digit in exponent + { s.1e-; } //~ ERROR unexpected token: `1e-` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-` + //~| ERROR expected at least one digit in exponent + { s.1e+1; } //~ ERROR unexpected token: `1e+1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1` + { s.1e-1; } //~ ERROR unexpected token: `1e-1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1` + { s.1.1e+1; } //~ ERROR unexpected token: `1.1e+1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1` + { s.1.1e-1; } //~ ERROR unexpected token: `1.1e-1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1` + s.0x1e1; //~ ERROR no field `0x1e1` on type `S` + s.0x1.; //~ ERROR no field `0x1` on type `S` + //~| ERROR hexadecimal float literal is not supported + //~| ERROR unexpected token: `;` + s.0x1.1; //~ ERROR no field `0x1` on type `S` + //~| ERROR hexadecimal float literal is not supported + s.0x1.1e1; //~ ERROR no field `0x1` on type `S` + //~| ERROR hexadecimal float literal is not supported + { s.0x1e+; } //~ ERROR expected expression, found `;` + { s.0x1e-; } //~ ERROR expected expression, found `;` + s.0x1e+1; //~ ERROR no field `0x1e` on type `S` + s.0x1e-1; //~ ERROR no field `0x1e` on type `S` + { s.0x1.1e+1; } //~ ERROR unexpected token: `0x1.1e+1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1` + //~| ERROR hexadecimal float literal is not supported + { s.0x1.1e-1; } //~ ERROR unexpected token: `0x1.1e-1` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1` + //~| ERROR hexadecimal float literal is not supported + s.1e1f32; //~ ERROR no field `1e1` on type `S` + //~| ERROR suffixes on a tuple index are invalid + s.1.f32; //~ ERROR no field `f32` on type `(u8, u8)` + s.1.1f32; //~ ERROR suffixes on a tuple index are invalid + s.1.1e1f32; //~ ERROR no field `1e1` on type `(u8, u8)` + //~| ERROR suffixes on a tuple index are invalid + { s.1e+f32; } //~ ERROR unexpected token: `1e+f32` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32` + //~| ERROR expected at least one digit in exponent + { s.1e-f32; } //~ ERROR unexpected token: `1e-f32` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32` + //~| ERROR expected at least one digit in exponent + { s.1e+1f32; } //~ ERROR unexpected token: `1e+1f32` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32` + { s.1e-1f32; } //~ ERROR unexpected token: `1e-1f32` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32` + { s.1.1e+1f32; } //~ ERROR unexpected token: `1.1e+1f32` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32` + { s.1.1e-1f32; } //~ ERROR unexpected token: `1.1e-1f32` + //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32` +} diff --git a/src/test/ui/parser/float-field.stderr b/src/test/ui/parser/float-field.stderr new file mode 100644 index 000000000..7090efc50 --- /dev/null +++ b/src/test/ui/parser/float-field.stderr @@ -0,0 +1,349 @@ +error: expected at least one digit in exponent + --> $DIR/float-field.rs:10:9 + | +LL | { s.1e+; } + | ^^^ + +error: expected at least one digit in exponent + --> $DIR/float-field.rs:13:9 + | +LL | { s.1e-; } + | ^^^ + +error: hexadecimal float literal is not supported + --> $DIR/float-field.rs:25:7 + | +LL | s.0x1.; + | ^^^^ + +error: hexadecimal float literal is not supported + --> $DIR/float-field.rs:28:7 + | +LL | s.0x1.1; + | ^^^^^ + +error: hexadecimal float literal is not supported + --> $DIR/float-field.rs:30:7 + | +LL | s.0x1.1e1; + | ^^^^^^^ + +error: hexadecimal float literal is not supported + --> $DIR/float-field.rs:36:9 + | +LL | { s.0x1.1e+1; } + | ^^^^^^^^ + +error: hexadecimal float literal is not supported + --> $DIR/float-field.rs:39:9 + | +LL | { s.0x1.1e-1; } + | ^^^^^^^^ + +error: expected at least one digit in exponent + --> $DIR/float-field.rs:48:9 + | +LL | { s.1e+f32; } + | ^^^^^^ + +error: expected at least one digit in exponent + --> $DIR/float-field.rs:51:9 + | +LL | { s.1e-f32; } + | ^^^^^^ + +error: unexpected token: `;` + --> $DIR/float-field.rs:7:9 + | +LL | s.1.; + | ^ + +error: unexpected token: `1e+` + --> $DIR/float-field.rs:10:9 + | +LL | { s.1e+; } + | ^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+` + --> $DIR/float-field.rs:10:9 + | +LL | { s.1e+; } + | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1e-` + --> $DIR/float-field.rs:13:9 + | +LL | { s.1e-; } + | ^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-` + --> $DIR/float-field.rs:13:9 + | +LL | { s.1e-; } + | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1e+1` + --> $DIR/float-field.rs:16:9 + | +LL | { s.1e+1; } + | ^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1` + --> $DIR/float-field.rs:16:9 + | +LL | { s.1e+1; } + | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1e-1` + --> $DIR/float-field.rs:18:9 + | +LL | { s.1e-1; } + | ^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1` + --> $DIR/float-field.rs:18:9 + | +LL | { s.1e-1; } + | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1.1e+1` + --> $DIR/float-field.rs:20:9 + | +LL | { s.1.1e+1; } + | ^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1` + --> $DIR/float-field.rs:20:9 + | +LL | { s.1.1e+1; } + | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1.1e-1` + --> $DIR/float-field.rs:22:9 + | +LL | { s.1.1e-1; } + | ^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1` + --> $DIR/float-field.rs:22:9 + | +LL | { s.1.1e-1; } + | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `;` + --> $DIR/float-field.rs:25:11 + | +LL | s.0x1.; + | ^ + +error: expected expression, found `;` + --> $DIR/float-field.rs:32:14 + | +LL | { s.0x1e+; } + | ^ expected expression + +error: expected expression, found `;` + --> $DIR/float-field.rs:33:14 + | +LL | { s.0x1e-; } + | ^ expected expression + +error: unexpected token: `0x1.1e+1` + --> $DIR/float-field.rs:36:9 + | +LL | { s.0x1.1e+1; } + | ^^^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1` + --> $DIR/float-field.rs:36:9 + | +LL | { s.0x1.1e+1; } + | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `0x1.1e-1` + --> $DIR/float-field.rs:39:9 + | +LL | { s.0x1.1e-1; } + | ^^^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1` + --> $DIR/float-field.rs:39:9 + | +LL | { s.0x1.1e-1; } + | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: suffixes on a tuple index are invalid + --> $DIR/float-field.rs:42:7 + | +LL | s.1e1f32; + | ^^^^^^ invalid suffix `f32` + +error: suffixes on a tuple index are invalid + --> $DIR/float-field.rs:45:7 + | +LL | s.1.1f32; + | ^^^^^^ invalid suffix `f32` + +error: suffixes on a tuple index are invalid + --> $DIR/float-field.rs:46:7 + | +LL | s.1.1e1f32; + | ^^^^^^^^ invalid suffix `f32` + +error: unexpected token: `1e+f32` + --> $DIR/float-field.rs:48:9 + | +LL | { s.1e+f32; } + | ^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32` + --> $DIR/float-field.rs:48:9 + | +LL | { s.1e+f32; } + | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1e-f32` + --> $DIR/float-field.rs:51:9 + | +LL | { s.1e-f32; } + | ^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32` + --> $DIR/float-field.rs:51:9 + | +LL | { s.1e-f32; } + | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1e+1f32` + --> $DIR/float-field.rs:54:9 + | +LL | { s.1e+1f32; } + | ^^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32` + --> $DIR/float-field.rs:54:9 + | +LL | { s.1e+1f32; } + | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1e-1f32` + --> $DIR/float-field.rs:56:9 + | +LL | { s.1e-1f32; } + | ^^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32` + --> $DIR/float-field.rs:56:9 + | +LL | { s.1e-1f32; } + | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1.1e+1f32` + --> $DIR/float-field.rs:58:9 + | +LL | { s.1.1e+1f32; } + | ^^^^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32` + --> $DIR/float-field.rs:58:9 + | +LL | { s.1.1e+1f32; } + | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: unexpected token: `1.1e-1f32` + --> $DIR/float-field.rs:60:9 + | +LL | { s.1.1e-1f32; } + | ^^^^^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32` + --> $DIR/float-field.rs:60:9 + | +LL | { s.1.1e-1f32; } + | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error[E0609]: no field `1e1` on type `S` + --> $DIR/float-field.rs:6:7 + | +LL | s.1e1; + | ^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `1e1` on type `(u8, u8)` + --> $DIR/float-field.rs:9:9 + | +LL | s.1.1e1; + | ^^^ + +error[E0609]: no field `0x1e1` on type `S` + --> $DIR/float-field.rs:24:7 + | +LL | s.0x1e1; + | ^^^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `0x1` on type `S` + --> $DIR/float-field.rs:25:7 + | +LL | s.0x1.; + | ^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `0x1` on type `S` + --> $DIR/float-field.rs:28:7 + | +LL | s.0x1.1; + | ^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `0x1` on type `S` + --> $DIR/float-field.rs:30:7 + | +LL | s.0x1.1e1; + | ^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `0x1e` on type `S` + --> $DIR/float-field.rs:34:7 + | +LL | s.0x1e+1; + | ^^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `0x1e` on type `S` + --> $DIR/float-field.rs:35:7 + | +LL | s.0x1e-1; + | ^^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `1e1` on type `S` + --> $DIR/float-field.rs:42:7 + | +LL | s.1e1f32; + | ^^^^^^ unknown field + | + = note: available fields are: `0`, `1` + +error[E0609]: no field `f32` on type `(u8, u8)` + --> $DIR/float-field.rs:44:9 + | +LL | s.1.f32; + | ^^^ + +error[E0609]: no field `1e1` on type `(u8, u8)` + --> $DIR/float-field.rs:46:7 + | +LL | s.1.1e1f32; + | ^^^^^^^^ + +error: aborting due to 55 previous errors + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/parser/float-literals.rs b/src/test/ui/parser/float-literals.rs new file mode 100644 index 000000000..1e9319fd2 --- /dev/null +++ b/src/test/ui/parser/float-literals.rs @@ -0,0 +1,9 @@ +// build-pass +// ignore-tidy-linelength +// Regression test for #31109 and #31407. + +pub fn main() { + let _: f64 = 0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333; + + let _: f64 = 1234567890123456789012345678901234567890e-340; +} diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs new file mode 100644 index 000000000..21d753ad0 --- /dev/null +++ b/src/test/ui/parser/fn-arg-doc-comment.rs @@ -0,0 +1,30 @@ +pub fn f( //~ NOTE function defined here + /// Comment + //~^ ERROR documentation comments cannot be applied to function parameters + //~| NOTE doc comments are not allowed here + //~| NOTE + id: u8, + /// Other + //~^ ERROR documentation comments cannot be applied to function parameters + //~| NOTE doc comments are not allowed here + //~| NOTE + a: u8, +) {} + +fn bar(id: #[allow(dead_code)] i32) {} +//~^ ERROR attributes cannot be applied to a function parameter's type +//~| NOTE attributes are not allowed here +//~| NOTE function defined here +//~| NOTE + +fn main() { + // verify that the parser recovered and properly typechecked the args + f("", ""); + //~^ ERROR arguments to this function are incorrect + //~| NOTE expected `u8`, found `&str` + //~| NOTE expected `u8`, found `&str` + bar(""); + //~^ ERROR mismatched types + //~| NOTE arguments to this function are incorrect + //~| NOTE expected `i32`, found `&str` +} diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr new file mode 100644 index 000000000..c8d7e2efe --- /dev/null +++ b/src/test/ui/parser/fn-arg-doc-comment.stderr @@ -0,0 +1,61 @@ +error: attributes cannot be applied to a function parameter's type + --> $DIR/fn-arg-doc-comment.rs:14:12 + | +LL | fn bar(id: #[allow(dead_code)] i32) {} + | ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: documentation comments cannot be applied to function parameters + --> $DIR/fn-arg-doc-comment.rs:2:5 + | +LL | /// Comment + | ^^^^^^^^^^^ doc comments are not allowed here + +error: documentation comments cannot be applied to function parameters + --> $DIR/fn-arg-doc-comment.rs:7:5 + | +LL | /// Other + | ^^^^^^^^^ doc comments are not allowed here + +error[E0308]: arguments to this function are incorrect + --> $DIR/fn-arg-doc-comment.rs:22:5 + | +LL | f("", ""); + | ^ -- -- expected `u8`, found `&str` + | | + | expected `u8`, found `&str` + | +note: function defined here + --> $DIR/fn-arg-doc-comment.rs:1:8 + | +LL | pub fn f( + | ^ +LL | / /// Comment +LL | | +LL | | +LL | | +LL | | id: u8, + | |__________- +LL | / /// Other +LL | | +LL | | +LL | | +LL | | a: u8, + | |_________- + +error[E0308]: mismatched types + --> $DIR/fn-arg-doc-comment.rs:26:9 + | +LL | bar(""); + | --- ^^ expected `i32`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/fn-arg-doc-comment.rs:14:4 + | +LL | fn bar(id: #[allow(dead_code)] i32) {} + | ^^^ --------------------------- + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/fn-body-eq-expr-semi.rs b/src/test/ui/parser/fn-body-eq-expr-semi.rs new file mode 100644 index 000000000..7127ba8da --- /dev/null +++ b/src/test/ui/parser/fn-body-eq-expr-semi.rs @@ -0,0 +1,23 @@ +fn main() {} + +fn syntax() { + fn foo() = 42; //~ ERROR function body cannot be `= expression;` + fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;` +} + +extern "C" { + fn foo() = 42; //~ ERROR function body cannot be `= expression;` + //~^ ERROR incorrect function inside `extern` block + fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;` + //~^ ERROR incorrect function inside `extern` block +} + +trait Foo { + fn foo() = 42; //~ ERROR function body cannot be `= expression;` + fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;` +} + +impl Foo for () { + fn foo() = 42; //~ ERROR function body cannot be `= expression;` + fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;` +} diff --git a/src/test/ui/parser/fn-body-eq-expr-semi.stderr b/src/test/ui/parser/fn-body-eq-expr-semi.stderr new file mode 100644 index 000000000..f1255d864 --- /dev/null +++ b/src/test/ui/parser/fn-body-eq-expr-semi.stderr @@ -0,0 +1,117 @@ +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:4:14 + | +LL | fn foo() = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn foo() { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:5:20 + | +LL | fn bar() -> u8 = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn bar() -> u8 { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:9:14 + | +LL | fn foo() = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn foo() { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:11:20 + | +LL | fn bar() -> u8 = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn bar() -> u8 { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:16:14 + | +LL | fn foo() = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn foo() { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:17:20 + | +LL | fn bar() -> u8 = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn bar() -> u8 { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:21:14 + | +LL | fn foo() = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn foo() { 42 } + | ~ ~ + +error: function body cannot be `= expression;` + --> $DIR/fn-body-eq-expr-semi.rs:22:20 + | +LL | fn bar() -> u8 = 42; + | ^^^^^ + | +help: surround the expression with `{` and `}` instead of `=` and `;` + | +LL | fn bar() -> u8 { 42 } + | ~ ~ + +error: incorrect function inside `extern` block + --> $DIR/fn-body-eq-expr-semi.rs:9:8 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body +LL | fn foo() = 42; + | ^^^ ----- help: remove the invalid body: `;` + | | + | cannot have a body + | + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: incorrect function inside `extern` block + --> $DIR/fn-body-eq-expr-semi.rs:11:8 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body +... +LL | fn bar() -> u8 = 42; + | ^^^ ----- help: remove the invalid body: `;` + | | + | cannot have a body + | + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 10 previous errors + diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.rs b/src/test/ui/parser/fn-body-optional-semantic-fail.rs new file mode 100644 index 000000000..12df48880 --- /dev/null +++ b/src/test/ui/parser/fn-body-optional-semantic-fail.rs @@ -0,0 +1,27 @@ +// Tests the different rules for `fn` forms requiring the presence or lack of a body. + +fn main() { + fn f1(); //~ ERROR free function without a body + fn f2() {} // OK. + + trait X { + fn f1(); // OK. + fn f2() {} // OK. + } + + struct Y; + impl X for Y { + fn f1(); //~ ERROR associated function in `impl` without body + fn f2() {} // OK. + } + + impl Y { + fn f3(); //~ ERROR associated function in `impl` without body + fn f4() {} // OK. + } + + extern "C" { + fn f5(); // OK. + fn f6() {} //~ ERROR incorrect function inside `extern` block + } +} diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.stderr b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr new file mode 100644 index 000000000..14bcd7c16 --- /dev/null +++ b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr @@ -0,0 +1,40 @@ +error: free function without a body + --> $DIR/fn-body-optional-semantic-fail.rs:4:5 + | +LL | fn f1(); + | ^^^^^^^- + | | + | help: provide a definition for the function: `{ <body> }` + +error: associated function in `impl` without body + --> $DIR/fn-body-optional-semantic-fail.rs:14:9 + | +LL | fn f1(); + | ^^^^^^^- + | | + | help: provide a definition for the function: `{ <body> }` + +error: associated function in `impl` without body + --> $DIR/fn-body-optional-semantic-fail.rs:19:9 + | +LL | fn f3(); + | ^^^^^^^- + | | + | help: provide a definition for the function: `{ <body> }` + +error: incorrect function inside `extern` block + --> $DIR/fn-body-optional-semantic-fail.rs:25:12 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body +LL | fn f5(); // OK. +LL | fn f6() {} + | ^^ -- help: remove the invalid body: `;` + | | + | cannot have a body + | + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/fn-body-optional-syntactic-pass.rs b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs new file mode 100644 index 000000000..f9dbebf0b --- /dev/null +++ b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs @@ -0,0 +1,31 @@ +// Ensures that all `fn` forms having or lacking a body are syntactically valid. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + fn f(); + fn f() {} + + trait X { + fn f(); + fn f() {} + } + + impl X for Y { + fn f(); + fn f() {} + } + + impl Y { + fn f(); + fn f() {} + } + + extern "C" { + fn f(); + fn f(); + } +} diff --git a/src/test/ui/parser/fn-colon-return-type.rs b/src/test/ui/parser/fn-colon-return-type.rs new file mode 100644 index 000000000..0001ef57c --- /dev/null +++ b/src/test/ui/parser/fn-colon-return-type.rs @@ -0,0 +1,6 @@ +fn foo(x: i32): i32 { +//~^ ERROR return types are denoted using `->` + x +} + +fn main() {} diff --git a/src/test/ui/parser/fn-colon-return-type.stderr b/src/test/ui/parser/fn-colon-return-type.stderr new file mode 100644 index 000000000..1de918782 --- /dev/null +++ b/src/test/ui/parser/fn-colon-return-type.stderr @@ -0,0 +1,8 @@ +error: return types are denoted using `->` + --> $DIR/fn-colon-return-type.rs:1:15 + | +LL | fn foo(x: i32): i32 { + | ^ help: use `->` instead + +error: aborting due to previous error + diff --git a/src/test/ui/parser/fn-field-parse-error-ice.rs b/src/test/ui/parser/fn-field-parse-error-ice.rs new file mode 100644 index 000000000..4ea55062f --- /dev/null +++ b/src/test/ui/parser/fn-field-parse-error-ice.rs @@ -0,0 +1,10 @@ +// Regression test for #85794 + +struct Baz { + inner : dyn fn () + //~^ ERROR expected `,`, or `}`, found keyword `fn` + //~| ERROR functions are not allowed in struct definitions + //~| ERROR cannot find type `dyn` in this scope +} + +fn main() {} diff --git a/src/test/ui/parser/fn-field-parse-error-ice.stderr b/src/test/ui/parser/fn-field-parse-error-ice.stderr new file mode 100644 index 000000000..d582f61cc --- /dev/null +++ b/src/test/ui/parser/fn-field-parse-error-ice.stderr @@ -0,0 +1,24 @@ +error: expected `,`, or `}`, found keyword `fn` + --> $DIR/fn-field-parse-error-ice.rs:4:16 + | +LL | inner : dyn fn () + | ^ help: try adding a comma: `,` + +error: functions are not allowed in struct definitions + --> $DIR/fn-field-parse-error-ice.rs:4:17 + | +LL | inner : dyn fn () + | ^^ + | + = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks + = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information + +error[E0412]: cannot find type `dyn` in this scope + --> $DIR/fn-field-parse-error-ice.rs:4:13 + | +LL | inner : dyn fn () + | ^^^ not found in this scope + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs new file mode 100644 index 000000000..8ff14fb1f --- /dev/null +++ b/src/test/ui/parser/fn-header-semantic-fail.rs @@ -0,0 +1,60 @@ +// Ensures that all `fn` forms can have all the function qualifiers syntactically. + +// edition:2018 + +#![feature(const_extern_fn)] + +fn main() { + async fn ff1() {} // OK. + unsafe fn ff2() {} // OK. + const fn ff3() {} // OK. + extern "C" fn ff4() {} // OK. + const async unsafe extern "C" fn ff5() {} + //~^ ERROR functions cannot be both `const` and `async` + //~| ERROR cycle detected + + trait X { + async fn ft1(); //~ ERROR functions in traits cannot be declared `async` + unsafe fn ft2(); // OK. + const fn ft3(); //~ ERROR functions in traits cannot be declared const + extern "C" fn ft4(); // OK. + const async unsafe extern "C" fn ft5(); + //~^ ERROR functions in traits cannot be declared `async` + //~| ERROR functions in traits cannot be declared const + //~| ERROR functions cannot be both `const` and `async` + } + + struct Y; + impl X for Y { + async fn ft1() {} //~ ERROR functions in traits cannot be declared `async` + //~^ ERROR has an incompatible type for trait + unsafe fn ft2() {} // OK. + const fn ft3() {} //~ ERROR functions in traits cannot be declared const + extern "C" fn ft4() {} + const async unsafe extern "C" fn ft5() {} + //~^ ERROR functions in traits cannot be declared `async` + //~| ERROR functions in traits cannot be declared const + //~| ERROR functions cannot be both `const` and `async` + //~| ERROR cycle detected + //~| ERROR has an incompatible type for trait + } + + impl Y { + async fn fi1() {} // OK. + unsafe fn fi2() {} // OK. + const fn fi3() {} // OK. + extern "C" fn fi4() {} // OK. + const async unsafe extern "C" fn fi5() {} + //~^ ERROR functions cannot be both `const` and `async` + //~| ERROR cycle detected + } + + extern "C" { + async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers + unsafe fn fe2(); //~ ERROR functions in `extern` blocks cannot have qualifiers + const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers + extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers + const async unsafe extern "C" fn fe5(); //~ ERROR functions in `extern` blocks + //~^ ERROR functions cannot be both `const` and `async` + } +} diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr new file mode 100644 index 000000000..bc51ba8b8 --- /dev/null +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -0,0 +1,330 @@ +error: functions cannot be both `const` and `async` + --> $DIR/fn-header-semantic-fail.rs:12:5 + | +LL | const async unsafe extern "C" fn ff5() {} + | ^^^^^-^^^^^------------------------------ + | | | + | | `async` because of this + | `const` because of this + +error[E0706]: functions in traits cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:17:9 + | +LL | async fn ft1(); + | -----^^^^^^^^^^ + | | + | `async` because of this + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error[E0379]: functions in traits cannot be declared const + --> $DIR/fn-header-semantic-fail.rs:19:9 + | +LL | const fn ft3(); + | ^^^^^ functions in traits cannot be const + +error[E0379]: functions in traits cannot be declared const + --> $DIR/fn-header-semantic-fail.rs:21:9 + | +LL | const async unsafe extern "C" fn ft5(); + | ^^^^^ functions in traits cannot be const + +error[E0706]: functions in traits cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:21:9 + | +LL | const async unsafe extern "C" fn ft5(); + | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error: functions cannot be both `const` and `async` + --> $DIR/fn-header-semantic-fail.rs:21:9 + | +LL | const async unsafe extern "C" fn ft5(); + | ^^^^^-^^^^^---------------------------- + | | | + | | `async` because of this + | `const` because of this + +error[E0706]: functions in traits cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:29:9 + | +LL | async fn ft1() {} + | -----^^^^^^^^^^^^ + | | + | `async` because of this + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error[E0379]: functions in traits cannot be declared const + --> $DIR/fn-header-semantic-fail.rs:32:9 + | +LL | const fn ft3() {} + | ^^^^^ functions in traits cannot be const + +error[E0379]: functions in traits cannot be declared const + --> $DIR/fn-header-semantic-fail.rs:34:9 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^^^^^ functions in traits cannot be const + +error[E0706]: functions in traits cannot be declared `async` + --> $DIR/fn-header-semantic-fail.rs:34:9 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error: functions cannot be both `const` and `async` + --> $DIR/fn-header-semantic-fail.rs:34:9 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^^^^^-^^^^^------------------------------ + | | | + | | `async` because of this + | `const` because of this + +error: functions cannot be both `const` and `async` + --> $DIR/fn-header-semantic-fail.rs:47:9 + | +LL | const async unsafe extern "C" fn fi5() {} + | ^^^^^-^^^^^------------------------------ + | | | + | | `async` because of this + | `const` because of this + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:53:18 + | +LL | extern "C" { + | ---------- in this `extern` block +LL | async fn fe1(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn fe1(); + | ~~ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:54:19 + | +LL | extern "C" { + | ---------- in this `extern` block +LL | async fn fe1(); +LL | unsafe fn fe2(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn fe2(); + | ~~ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:55:18 + | +LL | extern "C" { + | ---------- in this `extern` block +... +LL | const fn fe3(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn fe3(); + | ~~ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:56:23 + | +LL | extern "C" { + | ---------- in this `extern` block +... +LL | extern "C" fn fe4(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn fe4(); + | ~~ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/fn-header-semantic-fail.rs:57:42 + | +LL | extern "C" { + | ---------- in this `extern` block +... +LL | const async unsafe extern "C" fn fe5(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn fe5(); + | ~~ + +error: functions cannot be both `const` and `async` + --> $DIR/fn-header-semantic-fail.rs:57:9 + | +LL | const async unsafe extern "C" fn fe5(); + | ^^^^^-^^^^^---------------------------- + | | | + | | `async` because of this + | `const` because of this + +error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}` + --> $DIR/fn-header-semantic-fail.rs:12:44 + | +LL | const async unsafe extern "C" fn ff5() {} + | ^ + | +note: ...which requires borrow-checking `main::ff5`... + --> $DIR/fn-header-semantic-fail.rs:12:5 + | +LL | const async unsafe extern "C" fn ff5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing `main::ff5`... + --> $DIR/fn-header-semantic-fail.rs:12:5 + | +LL | const async unsafe extern "C" fn ff5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `main::ff5`... + --> $DIR/fn-header-semantic-fail.rs:12:5 + | +LL | const async unsafe extern "C" fn ff5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... + = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... + = note: ...which again requires computing type of `main::ff5::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/fn-header-semantic-fail.rs:5:1 + | +LL | / #![feature(const_extern_fn)] +LL | | +LL | | fn main() { +LL | | async fn ff1() {} // OK. +... | +LL | | } +LL | | } + | |_^ + +error[E0053]: method `ft1` has an incompatible type for trait + --> $DIR/fn-header-semantic-fail.rs:29:24 + | +LL | async fn ft1() {} + | ^ + | | + | checked the `Output` of this `async fn`, found opaque type + | expected `()`, found opaque type + | + = note: while checking the return type of the `async fn` +note: type in trait + --> $DIR/fn-header-semantic-fail.rs:17:23 + | +LL | async fn ft1(); + | ^ + = note: expected fn pointer `fn()` + found fn pointer `fn() -> impl Future<Output = ()>` + +error[E0053]: method `ft5` has an incompatible type for trait + --> $DIR/fn-header-semantic-fail.rs:34:48 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^ + | | + | checked the `Output` of this `async fn`, found opaque type + | expected `()`, found opaque type + | + = note: while checking the return type of the `async fn` +note: type in trait + --> $DIR/fn-header-semantic-fail.rs:21:47 + | +LL | const async unsafe extern "C" fn ft5(); + | ^ + = note: expected fn pointer `unsafe extern "C" fn()` + found fn pointer `unsafe extern "C" fn() -> impl Future<Output = ()>` + +error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}` + --> $DIR/fn-header-semantic-fail.rs:34:48 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^ + | +note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`... + --> $DIR/fn-header-semantic-fail.rs:34:9 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`... + --> $DIR/fn-header-semantic-fail.rs:34:9 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`... + --> $DIR/fn-header-semantic-fail.rs:34:9 + | +LL | const async unsafe extern "C" fn ft5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... + = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... + = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/fn-header-semantic-fail.rs:5:1 + | +LL | / #![feature(const_extern_fn)] +LL | | +LL | | fn main() { +LL | | async fn ff1() {} // OK. +... | +LL | | } +LL | | } + | |_^ + +error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}` + --> $DIR/fn-header-semantic-fail.rs:47:48 + | +LL | const async unsafe extern "C" fn fi5() {} + | ^ + | +note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`... + --> $DIR/fn-header-semantic-fail.rs:47:9 + | +LL | const async unsafe extern "C" fn fi5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`... + --> $DIR/fn-header-semantic-fail.rs:47:9 + | +LL | const async unsafe extern "C" fn fi5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`... + --> $DIR/fn-header-semantic-fail.rs:47:9 + | +LL | const async unsafe extern "C" fn fi5() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... + = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... + = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/fn-header-semantic-fail.rs:5:1 + | +LL | / #![feature(const_extern_fn)] +LL | | +LL | | fn main() { +LL | | async fn ff1() {} // OK. +... | +LL | | } +LL | | } + | |_^ + +error: aborting due to 23 previous errors + +Some errors have detailed explanations: E0053, E0379, E0391, E0706. +For more information about an error, try `rustc --explain E0053`. diff --git a/src/test/ui/parser/fn-header-syntactic-pass.rs b/src/test/ui/parser/fn-header-syntactic-pass.rs new file mode 100644 index 000000000..68f1f7901 --- /dev/null +++ b/src/test/ui/parser/fn-header-syntactic-pass.rs @@ -0,0 +1,47 @@ +// Ensures that all `fn` forms can have all the function qualifiers syntactically. + +// check-pass +// edition:2018 + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + + trait X { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } + + impl X for Y { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } + + impl Y { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } + + extern "C" { + fn f(); + fn f(); + fn f(); + fn f(); + fn f(); + } +} diff --git a/src/test/ui/parser/fn-returns-fn-pointer.rs b/src/test/ui/parser/fn-returns-fn-pointer.rs new file mode 100644 index 000000000..15590e324 --- /dev/null +++ b/src/test/ui/parser/fn-returns-fn-pointer.rs @@ -0,0 +1,6 @@ +// check-pass +// Regression test for #78507. +fn foo() -> Option<fn() -> Option<bool>> { + Some(|| Some(true)) +} +fn main() {} diff --git a/src/test/ui/parser/foreign-const-semantic-fail.rs b/src/test/ui/parser/foreign-const-semantic-fail.rs new file mode 100644 index 000000000..c9940b74a --- /dev/null +++ b/src/test/ui/parser/foreign-const-semantic-fail.rs @@ -0,0 +1,9 @@ +fn main() {} + +extern "C" { + const A: isize; + //~^ ERROR extern items cannot be `const` + const B: isize = 42; + //~^ ERROR extern items cannot be `const` + //~| ERROR incorrect `static` inside `extern` block +} diff --git a/src/test/ui/parser/foreign-const-semantic-fail.stderr b/src/test/ui/parser/foreign-const-semantic-fail.stderr new file mode 100644 index 000000000..8dc66c0d0 --- /dev/null +++ b/src/test/ui/parser/foreign-const-semantic-fail.stderr @@ -0,0 +1,35 @@ +error: extern items cannot be `const` + --> $DIR/foreign-const-semantic-fail.rs:4:11 + | +LL | const A: isize; + | ------^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: extern items cannot be `const` + --> $DIR/foreign-const-semantic-fail.rs:6:11 + | +LL | const B: isize = 42; + | ------^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: incorrect `static` inside `extern` block + --> $DIR/foreign-const-semantic-fail.rs:6:11 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body +... +LL | const B: isize = 42; + | ^ -- the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/foreign-const-syntactic-fail.rs b/src/test/ui/parser/foreign-const-syntactic-fail.rs new file mode 100644 index 000000000..a6e77f846 --- /dev/null +++ b/src/test/ui/parser/foreign-const-syntactic-fail.rs @@ -0,0 +1,9 @@ +// Syntactically, a `const` item inside an `extern { ... }` block is not allowed. + +fn main() {} + +#[cfg(FALSE)] +extern "C" { + const A: isize; //~ ERROR extern items cannot be `const` + const B: isize = 42; //~ ERROR extern items cannot be `const` +} diff --git a/src/test/ui/parser/foreign-const-syntactic-fail.stderr b/src/test/ui/parser/foreign-const-syntactic-fail.stderr new file mode 100644 index 000000000..9cf58fa95 --- /dev/null +++ b/src/test/ui/parser/foreign-const-syntactic-fail.stderr @@ -0,0 +1,22 @@ +error: extern items cannot be `const` + --> $DIR/foreign-const-syntactic-fail.rs:7:11 + | +LL | const A: isize; + | ------^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: extern items cannot be `const` + --> $DIR/foreign-const-syntactic-fail.rs:8:11 + | +LL | const B: isize = 42; + | ------^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/foreign-static-semantic-fail.rs b/src/test/ui/parser/foreign-static-semantic-fail.rs new file mode 100644 index 000000000..3d427ed0e --- /dev/null +++ b/src/test/ui/parser/foreign-static-semantic-fail.rs @@ -0,0 +1,8 @@ +// Syntactically, a foreign static may not have a body. + +fn main() {} + +extern "C" { + static X: u8 = 0; //~ ERROR incorrect `static` inside `extern` block + static mut Y: u8 = 0; //~ ERROR incorrect `static` inside `extern` block +} diff --git a/src/test/ui/parser/foreign-static-semantic-fail.stderr b/src/test/ui/parser/foreign-static-semantic-fail.stderr new file mode 100644 index 000000000..105508cfe --- /dev/null +++ b/src/test/ui/parser/foreign-static-semantic-fail.stderr @@ -0,0 +1,27 @@ +error: incorrect `static` inside `extern` block + --> $DIR/foreign-static-semantic-fail.rs:6:12 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body +LL | static X: u8 = 0; + | ^ - the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: incorrect `static` inside `extern` block + --> $DIR/foreign-static-semantic-fail.rs:7:16 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body +LL | static X: u8 = 0; +LL | static mut Y: u8 = 0; + | ^ - the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/foreign-static-syntactic-pass.rs b/src/test/ui/parser/foreign-static-syntactic-pass.rs new file mode 100644 index 000000000..599496346 --- /dev/null +++ b/src/test/ui/parser/foreign-static-syntactic-pass.rs @@ -0,0 +1,11 @@ +// Syntactically, a foreign static may have a body. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +extern "C" { + static X: u8; + static mut Y: u8; +} diff --git a/src/test/ui/parser/foreign-ty-semantic-fail.rs b/src/test/ui/parser/foreign-ty-semantic-fail.rs new file mode 100644 index 000000000..96b15232b --- /dev/null +++ b/src/test/ui/parser/foreign-ty-semantic-fail.rs @@ -0,0 +1,18 @@ +#![feature(extern_types)] + +fn main() {} + +extern "C" { + type A: Ord; + //~^ ERROR bounds on `type`s in `extern` blocks have no effect + type B<'a> where 'a: 'static; + //~^ ERROR `type`s inside `extern` blocks cannot have generic parameters + //~| ERROR `type`s inside `extern` blocks cannot have `where` clauses + type C<T: Ord> where T: 'static; + //~^ ERROR `type`s inside `extern` blocks cannot have generic parameters + //~| ERROR `type`s inside `extern` blocks cannot have `where` clauses + type D = u8; + //~^ ERROR incorrect `type` inside `extern` block + + type E: where; +} diff --git a/src/test/ui/parser/foreign-ty-semantic-fail.stderr b/src/test/ui/parser/foreign-ty-semantic-fail.stderr new file mode 100644 index 000000000..588e4966a --- /dev/null +++ b/src/test/ui/parser/foreign-ty-semantic-fail.stderr @@ -0,0 +1,65 @@ +error: bounds on `type`s in `extern` blocks have no effect + --> $DIR/foreign-ty-semantic-fail.rs:6:13 + | +LL | type A: Ord; + | ^^^ + +error: `type`s inside `extern` blocks cannot have generic parameters + --> $DIR/foreign-ty-semantic-fail.rs:8:11 + | +LL | extern "C" { + | ---------- `extern` block begins here +... +LL | type B<'a> where 'a: 'static; + | ^^^^ help: remove the generic parameters + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: `type`s inside `extern` blocks cannot have `where` clauses + --> $DIR/foreign-ty-semantic-fail.rs:8:16 + | +LL | extern "C" { + | ---------- `extern` block begins here +... +LL | type B<'a> where 'a: 'static; + | ^^^^^^^^^^^^^^^^^ help: remove the `where` clause + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: `type`s inside `extern` blocks cannot have generic parameters + --> $DIR/foreign-ty-semantic-fail.rs:11:11 + | +LL | extern "C" { + | ---------- `extern` block begins here +... +LL | type C<T: Ord> where T: 'static; + | ^^^^^^^^ help: remove the generic parameters + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: `type`s inside `extern` blocks cannot have `where` clauses + --> $DIR/foreign-ty-semantic-fail.rs:11:20 + | +LL | extern "C" { + | ---------- `extern` block begins here +... +LL | type C<T: Ord> where T: 'static; + | ^^^^^^^^^^^^^^^^ help: remove the `where` clause + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: incorrect `type` inside `extern` block + --> $DIR/foreign-ty-semantic-fail.rs:14:10 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body +... +LL | type D = u8; + | ^ -- the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/foreign-ty-syntactic-pass.rs b/src/test/ui/parser/foreign-ty-syntactic-pass.rs new file mode 100644 index 000000000..a746de1f1 --- /dev/null +++ b/src/test/ui/parser/foreign-ty-syntactic-pass.rs @@ -0,0 +1,12 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +extern "C" { + type A: Ord; + type A<'a> where 'a: 'static; + type A<T: Ord> where T: 'static; + type A = u8; + type A<'a: 'static, T: Ord + 'static>: Eq + PartialEq where T: 'static + Copy = Vec<u8>; +} diff --git a/src/test/ui/parser/if-block-unreachable-expr.rs b/src/test/ui/parser/if-block-unreachable-expr.rs new file mode 100644 index 000000000..4063a3370 --- /dev/null +++ b/src/test/ui/parser/if-block-unreachable-expr.rs @@ -0,0 +1,8 @@ +// check-pass + +// This regressed from 1.20 -> 1.21 -- the condition is unreachable, +// but it's still an expression, and should parse fine. + +fn main() { + if { if true { return; } else { return; }; } {} +} diff --git a/src/test/ui/parser/if-in-in.fixed b/src/test/ui/parser/if-in-in.fixed new file mode 100644 index 000000000..0bb88c559 --- /dev/null +++ b/src/test/ui/parser/if-in-in.fixed @@ -0,0 +1,7 @@ +// run-rustfix + +fn main() { + for i in 1..2 { //~ ERROR expected iterable, found keyword `in` + println!("{}", i); + } +} diff --git a/src/test/ui/parser/if-in-in.rs b/src/test/ui/parser/if-in-in.rs new file mode 100644 index 000000000..6c0986fe1 --- /dev/null +++ b/src/test/ui/parser/if-in-in.rs @@ -0,0 +1,7 @@ +// run-rustfix + +fn main() { + for i in in 1..2 { //~ ERROR expected iterable, found keyword `in` + println!("{}", i); + } +} diff --git a/src/test/ui/parser/if-in-in.stderr b/src/test/ui/parser/if-in-in.stderr new file mode 100644 index 000000000..0e69bc4b2 --- /dev/null +++ b/src/test/ui/parser/if-in-in.stderr @@ -0,0 +1,10 @@ +error: expected iterable, found keyword `in` + --> $DIR/if-in-in.rs:4:14 + | +LL | for i in in 1..2 { + | ---^^ + | | + | help: remove the duplicated `in` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/impl-item-const-pass.rs b/src/test/ui/parser/impl-item-const-pass.rs new file mode 100644 index 000000000..d11245613 --- /dev/null +++ b/src/test/ui/parser/impl-item-const-pass.rs @@ -0,0 +1,8 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +impl X { + const Y: u8; +} diff --git a/src/test/ui/parser/impl-item-const-semantic-fail.rs b/src/test/ui/parser/impl-item-const-semantic-fail.rs new file mode 100644 index 000000000..5d4692f9f --- /dev/null +++ b/src/test/ui/parser/impl-item-const-semantic-fail.rs @@ -0,0 +1,7 @@ +fn main() {} + +struct X; + +impl X { + const Y: u8; //~ ERROR associated constant in `impl` without body +} diff --git a/src/test/ui/parser/impl-item-const-semantic-fail.stderr b/src/test/ui/parser/impl-item-const-semantic-fail.stderr new file mode 100644 index 000000000..ec3bee0ce --- /dev/null +++ b/src/test/ui/parser/impl-item-const-semantic-fail.stderr @@ -0,0 +1,10 @@ +error: associated constant in `impl` without body + --> $DIR/impl-item-const-semantic-fail.rs:6:5 + | +LL | const Y: u8; + | ^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/impl-item-fn-no-body-pass.rs b/src/test/ui/parser/impl-item-fn-no-body-pass.rs new file mode 100644 index 000000000..16b09d64e --- /dev/null +++ b/src/test/ui/parser/impl-item-fn-no-body-pass.rs @@ -0,0 +1,8 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +impl X { + fn f(); +} diff --git a/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs new file mode 100644 index 000000000..cb183db59 --- /dev/null +++ b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs @@ -0,0 +1,7 @@ +fn main() {} + +struct X; + +impl X { + fn f(); //~ ERROR associated function in `impl` without body +} diff --git a/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr new file mode 100644 index 000000000..1acb72736 --- /dev/null +++ b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr @@ -0,0 +1,10 @@ +error: associated function in `impl` without body + --> $DIR/impl-item-fn-no-body-semantic-fail.rs:6:5 + | +LL | fn f(); + | ^^^^^^- + | | + | help: provide a definition for the function: `{ <body> }` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/impl-item-type-no-body-pass.rs b/src/test/ui/parser/impl-item-type-no-body-pass.rs new file mode 100644 index 000000000..74a9c6ab7 --- /dev/null +++ b/src/test/ui/parser/impl-item-type-no-body-pass.rs @@ -0,0 +1,11 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +impl X { + type Y; + type Z: Ord; + type W: Ord where Self: Eq; + type W where Self: Eq; +} diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs new file mode 100644 index 000000000..9871cb8fe --- /dev/null +++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs @@ -0,0 +1,22 @@ +#![feature(generic_associated_types)] + +fn main() {} + +struct X; + +impl X { + type Y; + //~^ ERROR associated type in `impl` without body + //~| ERROR inherent associated types are unstable + type Z: Ord; + //~^ ERROR associated type in `impl` without body + //~| ERROR bounds on `type`s in `impl`s have no effect + //~| ERROR inherent associated types are unstable + type W: Ord where Self: Eq; + //~^ ERROR associated type in `impl` without body + //~| ERROR bounds on `type`s in `impl`s have no effect + //~| ERROR inherent associated types are unstable + type W where Self: Eq; + //~^ ERROR associated type in `impl` without body + //~| ERROR inherent associated types are unstable +} diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr new file mode 100644 index 000000000..4b398d791 --- /dev/null +++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr @@ -0,0 +1,83 @@ +error: associated type in `impl` without body + --> $DIR/impl-item-type-no-body-semantic-fail.rs:8:5 + | +LL | type Y; + | ^^^^^^- + | | + | help: provide a definition for the type: `= <type>;` + +error: associated type in `impl` without body + --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:5 + | +LL | type Z: Ord; + | ^^^^^^^^^^^- + | | + | help: provide a definition for the type: `= <type>;` + +error: bounds on `type`s in `impl`s have no effect + --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:13 + | +LL | type Z: Ord; + | ^^^ + +error: associated type in `impl` without body + --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:5 + | +LL | type W: Ord where Self: Eq; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the type: `= <type>;` + +error: bounds on `type`s in `impl`s have no effect + --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:13 + | +LL | type W: Ord where Self: Eq; + | ^^^ + +error: associated type in `impl` without body + --> $DIR/impl-item-type-no-body-semantic-fail.rs:19:5 + | +LL | type W where Self: Eq; + | ^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the type: `= <type>;` + +error[E0658]: inherent associated types are unstable + --> $DIR/impl-item-type-no-body-semantic-fail.rs:8:5 + | +LL | type Y; + | ^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error[E0658]: inherent associated types are unstable + --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:5 + | +LL | type Z: Ord; + | ^^^^^^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error[E0658]: inherent associated types are unstable + --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:5 + | +LL | type W: Ord where Self: Eq; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error[E0658]: inherent associated types are unstable + --> $DIR/impl-item-type-no-body-semantic-fail.rs:19:5 + | +LL | type W where Self: Eq; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/parser/impl-parsing.rs b/src/test/ui/parser/impl-parsing.rs new file mode 100644 index 000000000..80ce88855 --- /dev/null +++ b/src/test/ui/parser/impl-parsing.rs @@ -0,0 +1,10 @@ +impl ! {} // OK +impl ! where u8: Copy {} // OK + +impl Trait Type {} //~ ERROR missing `for` in a trait impl +impl Trait .. {} //~ ERROR missing `for` in a trait impl +impl ?Sized for Type {} //~ ERROR expected a trait, found type +impl ?Sized for .. {} //~ ERROR expected a trait, found type + +default unsafe FAIL //~ ERROR expected item, found keyword `unsafe` +//~^ ERROR `default` is not followed by an item diff --git a/src/test/ui/parser/impl-parsing.stderr b/src/test/ui/parser/impl-parsing.stderr new file mode 100644 index 000000000..755addf14 --- /dev/null +++ b/src/test/ui/parser/impl-parsing.stderr @@ -0,0 +1,40 @@ +error: missing `for` in a trait impl + --> $DIR/impl-parsing.rs:4:11 + | +LL | impl Trait Type {} + | ^ help: add `for` here + +error: missing `for` in a trait impl + --> $DIR/impl-parsing.rs:5:11 + | +LL | impl Trait .. {} + | ^ help: add `for` here + +error: expected a trait, found type + --> $DIR/impl-parsing.rs:6:6 + | +LL | impl ?Sized for Type {} + | ^^^^^^ + +error: expected a trait, found type + --> $DIR/impl-parsing.rs:7:6 + | +LL | impl ?Sized for .. {} + | ^^^^^^ + +error: `default` is not followed by an item + --> $DIR/impl-parsing.rs:9:1 + | +LL | default unsafe FAIL + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: expected item, found keyword `unsafe` + --> $DIR/impl-parsing.rs:9:9 + | +LL | default unsafe FAIL + | ^^^^^^ expected item + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/impl-qpath.rs b/src/test/ui/parser/impl-qpath.rs new file mode 100644 index 000000000..d1f0a0204 --- /dev/null +++ b/src/test/ui/parser/impl-qpath.rs @@ -0,0 +1,7 @@ +// check-pass +// compile-flags: -Z parse-only + +impl <*const u8>::AssocTy {} // OK +impl <Type as Trait>::AssocTy {} // OK +impl <'a + Trait>::AssocTy {} // OK +impl <<Type>::AssocTy>::AssocTy {} // OK diff --git a/src/test/ui/parser/import-from-path.rs b/src/test/ui/parser/import-from-path.rs new file mode 100644 index 000000000..3fce08259 --- /dev/null +++ b/src/test/ui/parser/import-from-path.rs @@ -0,0 +1,2 @@ +// error-pattern:expected +use foo::{bar}::baz diff --git a/src/test/ui/parser/import-from-path.stderr b/src/test/ui/parser/import-from-path.stderr new file mode 100644 index 000000000..93bdf82d0 --- /dev/null +++ b/src/test/ui/parser/import-from-path.stderr @@ -0,0 +1,10 @@ +error: expected `;`, found `::` + --> $DIR/import-from-path.rs:2:15 + | +LL | use foo::{bar}::baz + | ^^ expected `;` + | + = note: glob-like brace syntax must be last on the path + +error: aborting due to previous error + diff --git a/src/test/ui/parser/import-from-rename.rs b/src/test/ui/parser/import-from-rename.rs new file mode 100644 index 000000000..27425a3c9 --- /dev/null +++ b/src/test/ui/parser/import-from-rename.rs @@ -0,0 +1,10 @@ +// error-pattern:expected + +use foo::{bar} as baz; + +mod foo { + pub fn bar() {} +} + +fn main() { +} diff --git a/src/test/ui/parser/import-from-rename.stderr b/src/test/ui/parser/import-from-rename.stderr new file mode 100644 index 000000000..d78f6de92 --- /dev/null +++ b/src/test/ui/parser/import-from-rename.stderr @@ -0,0 +1,10 @@ +error: expected `;`, found keyword `as` + --> $DIR/import-from-rename.rs:3:16 + | +LL | use foo::{bar} as baz; + | ^^ expected `;` + | + = note: glob-like brace syntax must be last on the path + +error: aborting due to previous error + diff --git a/src/test/ui/parser/import-glob-path.rs b/src/test/ui/parser/import-glob-path.rs new file mode 100644 index 000000000..de4c07aa7 --- /dev/null +++ b/src/test/ui/parser/import-glob-path.rs @@ -0,0 +1,2 @@ +// error-pattern:expected +use foo::*::bar diff --git a/src/test/ui/parser/import-glob-path.stderr b/src/test/ui/parser/import-glob-path.stderr new file mode 100644 index 000000000..a93ef255c --- /dev/null +++ b/src/test/ui/parser/import-glob-path.stderr @@ -0,0 +1,10 @@ +error: expected `;`, found `::` + --> $DIR/import-glob-path.rs:2:11 + | +LL | use foo::*::bar + | ^^ expected `;` + | + = note: the wildcard token must be last on the path + +error: aborting due to previous error + diff --git a/src/test/ui/parser/import-glob-rename.rs b/src/test/ui/parser/import-glob-rename.rs new file mode 100644 index 000000000..b9b753dcd --- /dev/null +++ b/src/test/ui/parser/import-glob-rename.rs @@ -0,0 +1,10 @@ +// error-pattern:expected + +use foo::* as baz; + +mod foo { + pub fn bar() {} +} + +fn main() { +} diff --git a/src/test/ui/parser/import-glob-rename.stderr b/src/test/ui/parser/import-glob-rename.stderr new file mode 100644 index 000000000..e1a026b63 --- /dev/null +++ b/src/test/ui/parser/import-glob-rename.stderr @@ -0,0 +1,10 @@ +error: expected `;`, found keyword `as` + --> $DIR/import-glob-rename.rs:3:12 + | +LL | use foo::* as baz; + | ^^ expected `;` + | + = note: the wildcard token must be last on the path + +error: aborting due to previous error + diff --git a/src/test/ui/parser/increment-autofix.fixed b/src/test/ui/parser/increment-autofix.fixed new file mode 100644 index 000000000..7a426badf --- /dev/null +++ b/src/test/ui/parser/increment-autofix.fixed @@ -0,0 +1,31 @@ +// run-rustfix + +pub fn pre_regular() { + let mut i = 0; + i += 1; //~ ERROR Rust has no prefix increment operator + println!("{}", i); +} + +pub fn pre_while() { + let mut i = 0; + while { i += 1; i } < 5 { + //~^ ERROR Rust has no prefix increment operator + println!("{}", i); + } +} + +pub fn pre_regular_tmp() { + let mut tmp = 0; + tmp += 1; //~ ERROR Rust has no prefix increment operator + println!("{}", tmp); +} + +pub fn pre_while_tmp() { + let mut tmp = 0; + while { tmp += 1; tmp } < 5 { + //~^ ERROR Rust has no prefix increment operator + println!("{}", tmp); + } +} + +fn main() {} diff --git a/src/test/ui/parser/increment-autofix.rs b/src/test/ui/parser/increment-autofix.rs new file mode 100644 index 000000000..d38603697 --- /dev/null +++ b/src/test/ui/parser/increment-autofix.rs @@ -0,0 +1,31 @@ +// run-rustfix + +pub fn pre_regular() { + let mut i = 0; + ++i; //~ ERROR Rust has no prefix increment operator + println!("{}", i); +} + +pub fn pre_while() { + let mut i = 0; + while ++i < 5 { + //~^ ERROR Rust has no prefix increment operator + println!("{}", i); + } +} + +pub fn pre_regular_tmp() { + let mut tmp = 0; + ++tmp; //~ ERROR Rust has no prefix increment operator + println!("{}", tmp); +} + +pub fn pre_while_tmp() { + let mut tmp = 0; + while ++tmp < 5 { + //~^ ERROR Rust has no prefix increment operator + println!("{}", tmp); + } +} + +fn main() {} diff --git a/src/test/ui/parser/increment-autofix.stderr b/src/test/ui/parser/increment-autofix.stderr new file mode 100644 index 000000000..1dc69fd9f --- /dev/null +++ b/src/test/ui/parser/increment-autofix.stderr @@ -0,0 +1,52 @@ +error: Rust has no prefix increment operator + --> $DIR/increment-autofix.rs:5:5 + | +LL | ++i; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL - ++i; +LL + i += 1; + | + +error: Rust has no prefix increment operator + --> $DIR/increment-autofix.rs:11:11 + | +LL | while ++i < 5 { + | ----- ^^ not a valid prefix operator + | | + | while parsing the condition of this `while` expression + | +help: use `+= 1` instead + | +LL | while { i += 1; i } < 5 { + | ~ +++++++++ + +error: Rust has no prefix increment operator + --> $DIR/increment-autofix.rs:19:5 + | +LL | ++tmp; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL - ++tmp; +LL + tmp += 1; + | + +error: Rust has no prefix increment operator + --> $DIR/increment-autofix.rs:25:11 + | +LL | while ++tmp < 5 { + | ----- ^^ not a valid prefix operator + | | + | while parsing the condition of this `while` expression + | +help: use `+= 1` instead + | +LL | while { tmp += 1; tmp } < 5 { + | ~ +++++++++++ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/increment-notfixed.rs b/src/test/ui/parser/increment-notfixed.rs new file mode 100644 index 000000000..15f159e53 --- /dev/null +++ b/src/test/ui/parser/increment-notfixed.rs @@ -0,0 +1,61 @@ +struct Foo { + bar: Bar, +} + +struct Bar { + qux: i32, +} + +pub fn post_regular() { + let mut i = 0; + i++; //~ ERROR Rust has no postfix increment operator + println!("{}", i); +} + +pub fn post_while() { + let mut i = 0; + while i++ < 5 { + //~^ ERROR Rust has no postfix increment operator + println!("{}", i); + } +} + +pub fn post_regular_tmp() { + let mut tmp = 0; + tmp++; //~ ERROR Rust has no postfix increment operator + println!("{}", tmp); +} + +pub fn post_while_tmp() { + let mut tmp = 0; + while tmp++ < 5 { + //~^ ERROR Rust has no postfix increment operator + println!("{}", tmp); + } +} + +pub fn post_field() { + let foo = Foo { bar: Bar { qux: 0 } }; + foo.bar.qux++; + //~^ ERROR Rust has no postfix increment operator + println!("{}", foo.bar.qux); +} + +pub fn post_field_tmp() { + struct S { + tmp: i32 + } + let s = S { tmp: 0 }; + s.tmp++; + //~^ ERROR Rust has no postfix increment operator + println!("{}", s.tmp); +} + +pub fn pre_field() { + let foo = Foo { bar: Bar { qux: 0 } }; + ++foo.bar.qux; + //~^ ERROR Rust has no prefix increment operator + println!("{}", foo.bar.qux); +} + +fn main() {} diff --git a/src/test/ui/parser/increment-notfixed.stderr b/src/test/ui/parser/increment-notfixed.stderr new file mode 100644 index 000000000..352d98cf8 --- /dev/null +++ b/src/test/ui/parser/increment-notfixed.stderr @@ -0,0 +1,102 @@ +error: Rust has no postfix increment operator + --> $DIR/increment-notfixed.rs:11:6 + | +LL | i++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | { let tmp = i; i += 1; tmp }; + | +++++++++++ ~~~~~~~~~~~~~~~ +LL - i++; +LL + i += 1; + | + +error: Rust has no postfix increment operator + --> $DIR/increment-notfixed.rs:17:12 + | +LL | while i++ < 5 { + | ----- ^^ not a valid postfix operator + | | + | while parsing the condition of this `while` expression + | +help: use `+= 1` instead + | +LL | while { let tmp = i; i += 1; tmp } < 5 { + | +++++++++++ ~~~~~~~~~~~~~~~ +LL - while i++ < 5 { +LL + while i += 1 < 5 { + | + +error: Rust has no postfix increment operator + --> $DIR/increment-notfixed.rs:25:8 + | +LL | tmp++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | { let tmp_ = tmp; tmp += 1; tmp_ }; + | ++++++++++++ ~~~~~~~~~~~~~~~~~~ +LL - tmp++; +LL + tmp += 1; + | + +error: Rust has no postfix increment operator + --> $DIR/increment-notfixed.rs:31:14 + | +LL | while tmp++ < 5 { + | ----- ^^ not a valid postfix operator + | | + | while parsing the condition of this `while` expression + | +help: use `+= 1` instead + | +LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { + | ++++++++++++ ~~~~~~~~~~~~~~~~~~ +LL - while tmp++ < 5 { +LL + while tmp += 1 < 5 { + | + +error: Rust has no postfix increment operator + --> $DIR/increment-notfixed.rs:39:16 + | +LL | foo.bar.qux++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp }; + | +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - foo.bar.qux++; +LL + foo.bar.qux += 1; + | + +error: Rust has no postfix increment operator + --> $DIR/increment-notfixed.rs:49:10 + | +LL | s.tmp++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | { let tmp = s.tmp; s.tmp += 1; tmp }; + | +++++++++++ ~~~~~~~~~~~~~~~~~~~ +LL - s.tmp++; +LL + s.tmp += 1; + | + +error: Rust has no prefix increment operator + --> $DIR/increment-notfixed.rs:56:5 + | +LL | ++foo.bar.qux; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL - ++foo.bar.qux; +LL + foo.bar.qux += 1; + | + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.rs b/src/test/ui/parser/inner-attr-after-doc-comment.rs new file mode 100644 index 000000000..36f4191f0 --- /dev/null +++ b/src/test/ui/parser/inner-attr-after-doc-comment.rs @@ -0,0 +1,8 @@ +#![feature(lang_items)] +/** + * My module + */ + +#![recursion_limit="100"] +//~^ ERROR an inner attribute is not permitted following an outer doc comment +fn main() {} diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.stderr b/src/test/ui/parser/inner-attr-after-doc-comment.stderr new file mode 100644 index 000000000..2cfafac77 --- /dev/null +++ b/src/test/ui/parser/inner-attr-after-doc-comment.stderr @@ -0,0 +1,23 @@ +error: an inner attribute is not permitted following an outer doc comment + --> $DIR/inner-attr-after-doc-comment.rs:6:1 + | +LL | / /** +LL | | * My module +LL | | */ + | |___- previous doc comment +LL | +LL | #![recursion_limit="100"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute +LL | +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![recursion_limit="100"] +LL + #[recursion_limit="100"] + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/inner-attr-in-trait-def.rs b/src/test/ui/parser/inner-attr-in-trait-def.rs new file mode 100644 index 000000000..8dba6b362 --- /dev/null +++ b/src/test/ui/parser/inner-attr-in-trait-def.rs @@ -0,0 +1,9 @@ +// check-pass + +#![deny(non_camel_case_types)] + +fn main() {} + +trait foo_bar { + #![allow(non_camel_case_types)] +} diff --git a/src/test/ui/parser/inner-attr.rs b/src/test/ui/parser/inner-attr.rs new file mode 100644 index 000000000..1b405e20e --- /dev/null +++ b/src/test/ui/parser/inner-attr.rs @@ -0,0 +1,4 @@ +#[feature(lang_items)] + +#![recursion_limit="100"] //~ ERROR an inner attribute is not permitted following an outer attribute +fn main() {} diff --git a/src/test/ui/parser/inner-attr.stderr b/src/test/ui/parser/inner-attr.stderr new file mode 100644 index 000000000..331c254a5 --- /dev/null +++ b/src/test/ui/parser/inner-attr.stderr @@ -0,0 +1,20 @@ +error: an inner attribute is not permitted following an outer attribute + --> $DIR/inner-attr.rs:3:1 + | +LL | #[feature(lang_items)] + | ---------------------- previous outer attribute +LL | +LL | #![recursion_limit="100"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![recursion_limit="100"] +LL + #[recursion_limit="100"] + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/int-literal-too-large-span.rs b/src/test/ui/parser/int-literal-too-large-span.rs new file mode 100644 index 000000000..666ca9350 --- /dev/null +++ b/src/test/ui/parser/int-literal-too-large-span.rs @@ -0,0 +1,7 @@ +// issue #17123 + +fn main() { + 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + //~^ ERROR integer literal is too large + ; // the span shouldn't point to this. +} diff --git a/src/test/ui/parser/int-literal-too-large-span.stderr b/src/test/ui/parser/int-literal-too-large-span.stderr new file mode 100644 index 000000000..7cae85fc9 --- /dev/null +++ b/src/test/ui/parser/int-literal-too-large-span.stderr @@ -0,0 +1,8 @@ +error: integer literal is too large + --> $DIR/int-literal-too-large-span.rs:4:5 + | +LL | 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns.rs new file mode 100644 index 000000000..a6d27aab4 --- /dev/null +++ b/src/test/ui/parser/intersection-patterns.rs @@ -0,0 +1,40 @@ +// This tests the parser recovery in `recover_intersection_pat` +// and serves as a regression test for the diagnostics issue #65400. +// +// The general idea is that for `$pat_lhs @ $pat_rhs` where +// `$pat_lhs` is not generated by `ref? mut? $ident` we want +// to suggest either switching the order or note that intersection +// patterns are not allowed. + +fn main() { + let s: Option<u8> = None; + + match s { + Some(x) @ y => {} + //~^ ERROR pattern on wrong side of `@` + //~| pattern on the left, should be on the right + //~| binding on the right, should be on the left + //~| HELP switch the order + //~| SUGGESTION y @ Some(x) + _ => {} + } + + match s { + Some(x) @ Some(y) => {} + //~^ ERROR left-hand side of `@` must be a binding + //~| interpreted as a pattern, not a binding + //~| also a pattern + //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x` + _ => {} + } + + match 2 { + 1 ..= 5 @ e => {} + //~^ ERROR pattern on wrong side of `@` + //~| pattern on the left, should be on the right + //~| binding on the right, should be on the left + //~| HELP switch the order + //~| SUGGESTION e @ 1..=5 + _ => {} + } +} diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns.stderr new file mode 100644 index 000000000..9dc4c469a --- /dev/null +++ b/src/test/ui/parser/intersection-patterns.stderr @@ -0,0 +1,33 @@ +error: pattern on wrong side of `@` + --> $DIR/intersection-patterns.rs:13:9 + | +LL | Some(x) @ y => {} + | -------^^^- + | | | + | | binding on the right, should be on the left + | pattern on the left, should be on the right + | help: switch the order: `y @ Some(x)` + +error: left-hand side of `@` must be a binding + --> $DIR/intersection-patterns.rs:23:9 + | +LL | Some(x) @ Some(y) => {} + | -------^^^------- + | | | + | | also a pattern + | interpreted as a pattern, not a binding + | + = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` + +error: pattern on wrong side of `@` + --> $DIR/intersection-patterns.rs:32:9 + | +LL | 1 ..= 5 @ e => {} + | -------^^^- + | | | + | | binding on the right, should be on the left + | pattern on the left, should be on the right + | help: switch the order: `e @ 1..=5` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs new file mode 100644 index 000000000..5c4272504 --- /dev/null +++ b/src/test/ui/parser/inverted-parameters.rs @@ -0,0 +1,32 @@ +struct S; + +impl S { + fn foo(&self, &str bar) {} + //~^ ERROR expected one of `:`, `@` + //~| HELP declare the type after the parameter binding + //~| SUGGESTION <identifier>: <type> +} + +fn baz(S quux, xyzzy: i32) {} +//~^ ERROR expected one of `:`, `@` +//~| HELP declare the type after the parameter binding +//~| SUGGESTION <identifier>: <type> + +fn one(i32 a b) {} +//~^ ERROR expected one of `:`, `@` + +fn pattern((i32, i32) (a, b)) {} +//~^ ERROR expected one of `:` + +fn fizz(i32) {} +//~^ ERROR expected one of `:`, `@` +//~| HELP if this is a parameter name, give it a type +//~| HELP if this is a `self` type, give it a parameter name +//~| HELP if this is a type, explicitly ignore the parameter name + +fn missing_colon(quux S) {} +//~^ ERROR expected one of `:`, `@` +//~| HELP declare the type after the parameter binding +//~| SUGGESTION <identifier>: <type> + +fn main() {} diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr new file mode 100644 index 000000000..866227782 --- /dev/null +++ b/src/test/ui/parser/inverted-parameters.stderr @@ -0,0 +1,61 @@ +error: expected one of `:`, `@`, or `|`, found `bar` + --> $DIR/inverted-parameters.rs:4:24 + | +LL | fn foo(&self, &str bar) {} + | -----^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `<identifier>: <type>` + +error: expected one of `:`, `@`, or `|`, found `quux` + --> $DIR/inverted-parameters.rs:10:10 + | +LL | fn baz(S quux, xyzzy: i32) {} + | --^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `<identifier>: <type>` + +error: expected one of `:`, `@`, or `|`, found `a` + --> $DIR/inverted-parameters.rs:15:12 + | +LL | fn one(i32 a b) {} + | ^ expected one of `:`, `@`, or `|` + +error: expected one of `:` or `|`, found `(` + --> $DIR/inverted-parameters.rs:18:23 + | +LL | fn pattern((i32, i32) (a, b)) {} + | ^ expected one of `:` or `|` + +error: expected one of `:`, `@`, or `|`, found `)` + --> $DIR/inverted-parameters.rs:21:12 + | +LL | fn fizz(i32) {} + | ^ expected one of `:`, `@`, or `|` + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn fizz(self: i32) {} + | +++++ +help: if this is a parameter name, give it a type + | +LL | fn fizz(i32: TypeName) {} + | ++++++++++ +help: if this is a type, explicitly ignore the parameter name + | +LL | fn fizz(_: i32) {} + | ++ + +error: expected one of `:`, `@`, or `|`, found `S` + --> $DIR/inverted-parameters.rs:27:23 + | +LL | fn missing_colon(quux S) {} + | -----^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `<identifier>: <type>` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issue-61858.rs b/src/test/ui/parser/issue-61858.rs new file mode 100644 index 000000000..6c3b56586 --- /dev/null +++ b/src/test/ui/parser/issue-61858.rs @@ -0,0 +1,3 @@ +fn main() { + (if foobar) //~ ERROR expected `{`, found `)` +} diff --git a/src/test/ui/parser/issue-61858.stderr b/src/test/ui/parser/issue-61858.stderr new file mode 100644 index 000000000..03f51c6e3 --- /dev/null +++ b/src/test/ui/parser/issue-61858.stderr @@ -0,0 +1,14 @@ +error: expected `{`, found `)` + --> $DIR/issue-61858.rs:2:15 + | +LL | (if foobar) + | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-61858.rs:2:9 + | +LL | (if foobar) + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs b/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs new file mode 100644 index 000000000..57d36feb3 --- /dev/null +++ b/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs @@ -0,0 +1,10 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* {} + //~^ ERROR missing condition for `if` expression + }; +} + +fn main() { + x!(if); +} diff --git a/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr new file mode 100644 index 000000000..6674b924e --- /dev/null +++ b/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr @@ -0,0 +1,10 @@ +error: missing condition for `if` expression + --> $DIR/issue-68091-unicode-ident-after-if.rs:3:14 + | +LL | $($c)ö* {} + | ^ - if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs new file mode 100644 index 000000000..1a90b4724 --- /dev/null +++ b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs @@ -0,0 +1,9 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression + }; +} + +fn main() { + x!(!); +} diff --git a/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr new file mode 100644 index 000000000..0b9c364f1 --- /dev/null +++ b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr @@ -0,0 +1,8 @@ +error: macro expansion ends with an incomplete expression: expected expression + --> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:14 + | +LL | $($c)ö* + | ^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-81804.rs b/src/test/ui/parser/issue-81804.rs new file mode 100644 index 000000000..803bde11e --- /dev/null +++ b/src/test/ui/parser/issue-81804.rs @@ -0,0 +1,9 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected pattern, found `=` +// error-pattern: expected one of `)`, `,`, `->`, `where`, or `{`, found `]` +// error-pattern: expected item, found `]` + +fn main() {} + +fn p([=(} diff --git a/src/test/ui/parser/issue-81804.stderr b/src/test/ui/parser/issue-81804.stderr new file mode 100644 index 000000000..19c4422c6 --- /dev/null +++ b/src/test/ui/parser/issue-81804.stderr @@ -0,0 +1,41 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-81804.rs:9:11 + | +LL | fn p([=(} + | -- ^ + | || + | |unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-81804.rs:9:11 + | +LL | fn p([=(} + | -- ^ + | || + | |unclosed delimiter + | unclosed delimiter + +error: expected pattern, found `=` + --> $DIR/issue-81804.rs:9:7 + | +LL | fn p([=(} + | ^ expected pattern + +error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]` + --> $DIR/issue-81804.rs:9:8 + | +LL | fn p([=(} + | ^ -^ + | | | + | | help: `)` may belong here + | unclosed delimiter + +error: expected item, found `]` + --> $DIR/issue-81804.rs:9:11 + | +LL | fn p([=(} + | ^ expected item + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/parser/issue-81827.rs b/src/test/ui/parser/issue-81827.rs new file mode 100644 index 000000000..7ec581594 --- /dev/null +++ b/src/test/ui/parser/issue-81827.rs @@ -0,0 +1,11 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: mismatched closing delimiter: `]` +// error-pattern: expected one of `)` or `,`, found `{` + +#![crate_name="0"] + + + +fn main() {} + +fn r()->i{0|{#[cfg(r(0{]0 diff --git a/src/test/ui/parser/issue-81827.stderr b/src/test/ui/parser/issue-81827.stderr new file mode 100644 index 000000000..069de3391 --- /dev/null +++ b/src/test/ui/parser/issue-81827.stderr @@ -0,0 +1,35 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-81827.rs:11:27 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-81827.rs:11:27 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: mismatched closing delimiter: `]` + --> $DIR/issue-81827.rs:11:23 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | - ^^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: expected one of `)` or `,`, found `{` + --> $DIR/issue-81827.rs:11:23 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | ^ expected one of `)` or `,` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/issue-87694-duplicated-pub.rs b/src/test/ui/parser/issue-87694-duplicated-pub.rs new file mode 100644 index 000000000..e3ea61dc4 --- /dev/null +++ b/src/test/ui/parser/issue-87694-duplicated-pub.rs @@ -0,0 +1,5 @@ +pub const pub fn test() {} +//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` +//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe` +//~| HELP there is already a visibility modifier, remove one +//~| NOTE explicit visibility first seen here diff --git a/src/test/ui/parser/issue-87694-duplicated-pub.stderr b/src/test/ui/parser/issue-87694-duplicated-pub.stderr new file mode 100644 index 000000000..8d242bc9d --- /dev/null +++ b/src/test/ui/parser/issue-87694-duplicated-pub.stderr @@ -0,0 +1,17 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-87694-duplicated-pub.rs:1:11 + | +LL | pub const pub fn test() {} + | ^^^ + | | + | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: there is already a visibility modifier, remove one + | +note: explicit visibility first seen here + --> $DIR/issue-87694-duplicated-pub.rs:1:1 + | +LL | pub const pub fn test() {} + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-87694-misplaced-pub.rs b/src/test/ui/parser/issue-87694-misplaced-pub.rs new file mode 100644 index 000000000..3f824617c --- /dev/null +++ b/src/test/ui/parser/issue-87694-misplaced-pub.rs @@ -0,0 +1,5 @@ +const pub fn test() {} +//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` +//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe` +//~| HELP visibility `pub` must come before `const` +//~| SUGGESTION pub const diff --git a/src/test/ui/parser/issue-87694-misplaced-pub.stderr b/src/test/ui/parser/issue-87694-misplaced-pub.stderr new file mode 100644 index 000000000..94c6a29ef --- /dev/null +++ b/src/test/ui/parser/issue-87694-misplaced-pub.stderr @@ -0,0 +1,11 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-87694-misplaced-pub.rs:1:7 + | +LL | const pub fn test() {} + | ------^^^ + | | | + | | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const`: `pub const` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-90728.rs b/src/test/ui/parser/issue-90728.rs new file mode 100644 index 000000000..d6a898361 --- /dev/null +++ b/src/test/ui/parser/issue-90728.rs @@ -0,0 +1,6 @@ +fn main() { + a.5.2E+ + //~^ ERROR: unexpected token: `5.2E+` + //~| ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+` + //~| ERROR: expected at least one digit in exponent +} diff --git a/src/test/ui/parser/issue-90728.stderr b/src/test/ui/parser/issue-90728.stderr new file mode 100644 index 000000000..b55c46030 --- /dev/null +++ b/src/test/ui/parser/issue-90728.stderr @@ -0,0 +1,20 @@ +error: expected at least one digit in exponent + --> $DIR/issue-90728.rs:2:7 + | +LL | a.5.2E+ + | ^^^^^ + +error: unexpected token: `5.2E+` + --> $DIR/issue-90728.rs:2:7 + | +LL | a.5.2E+ + | ^^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+` + --> $DIR/issue-90728.rs:2:7 + | +LL | a.5.2E+ + | ^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issue-91421.rs b/src/test/ui/parser/issue-91421.rs new file mode 100644 index 000000000..8bba27f37 --- /dev/null +++ b/src/test/ui/parser/issue-91421.rs @@ -0,0 +1,9 @@ +// Regression test for issue #91421. + +fn main() { + let value = if true && { + //~^ ERROR: this `if` expression is missing a block after the condition + //~| HELP: this binary operation is possibly unfinished + 3 + } else { 4 }; +} diff --git a/src/test/ui/parser/issue-91421.stderr b/src/test/ui/parser/issue-91421.stderr new file mode 100644 index 000000000..2d9652051 --- /dev/null +++ b/src/test/ui/parser/issue-91421.stderr @@ -0,0 +1,14 @@ +error: this `if` expression is missing a block after the condition + --> $DIR/issue-91421.rs:4:17 + | +LL | let value = if true && { + | ^^ + | +help: this binary operation is possibly unfinished + --> $DIR/issue-91421.rs:4:20 + | +LL | let value = if true && { + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed new file mode 100644 index 000000000..4b4a416b1 --- /dev/null +++ b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed @@ -0,0 +1,13 @@ +// run-rustfix + +pub enum Range { + //~^ ERROR `enum` and `struct` are mutually exclusive + Valid { + begin: u32, + len: u32, + }, + Out, +} + +fn main() { +} diff --git a/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs new file mode 100644 index 000000000..9cc886641 --- /dev/null +++ b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs @@ -0,0 +1,13 @@ +// run-rustfix + +pub enum struct Range { + //~^ ERROR `enum` and `struct` are mutually exclusive + Valid { + begin: u32, + len: u32, + }, + Out, +} + +fn main() { +} diff --git a/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr new file mode 100644 index 000000000..edc640bf5 --- /dev/null +++ b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr @@ -0,0 +1,8 @@ +error: `enum` and `struct` are mutually exclusive + --> $DIR/issue-99625-enum-struct-mutually-exclusive.rs:3:5 + | +LL | pub enum struct Range { + | ^^^^^^^^^^^ help: replace `enum struct` with: `enum` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs b/src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs new file mode 100644 index 000000000..32a3b9dcc --- /dev/null +++ b/src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs @@ -0,0 +1,3 @@ +// include file for issue-21146.rs + +parse_error diff --git a/src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs b/src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs new file mode 100644 index 000000000..e5604b816 --- /dev/null +++ b/src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(ICE)] +pub fn derive(_: TokenStream) -> TokenStream { + r#"#[allow(missing_docs)] struct X { }"#.parse().unwrap() +} diff --git a/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs b/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs new file mode 100644 index 000000000..9429e5143 --- /dev/null +++ b/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs @@ -0,0 +1,3 @@ +// include file for issue-94340.rs +#![deny(rust_2018_idioms)] +#![deny(unused_must_use)] diff --git a/src/test/ui/parser/issues/issue-10392-2.fixed b/src/test/ui/parser/issues/issue-10392-2.fixed new file mode 100644 index 000000000..3386fac17 --- /dev/null +++ b/src/test/ui/parser/issues/issue-10392-2.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +pub struct A { pub foo: isize } + +fn a() -> A { panic!() } + +fn main() { + let A { .. } = a(); //~ ERROR: expected `}` +} diff --git a/src/test/ui/parser/issues/issue-10392-2.rs b/src/test/ui/parser/issues/issue-10392-2.rs new file mode 100644 index 000000000..30628ae31 --- /dev/null +++ b/src/test/ui/parser/issues/issue-10392-2.rs @@ -0,0 +1,9 @@ +// run-rustfix + +pub struct A { pub foo: isize } + +fn a() -> A { panic!() } + +fn main() { + let A { .., } = a(); //~ ERROR: expected `}` +} diff --git a/src/test/ui/parser/issues/issue-10392-2.stderr b/src/test/ui/parser/issues/issue-10392-2.stderr new file mode 100644 index 000000000..4154ecfeb --- /dev/null +++ b/src/test/ui/parser/issues/issue-10392-2.stderr @@ -0,0 +1,12 @@ +error: expected `}`, found `,` + --> $DIR/issue-10392-2.rs:8:15 + | +LL | let A { .., } = a(); + | --^ + | | | + | | expected `}` + | | help: remove this comma + | `..` must be at the end and cannot have a trailing comma + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-10392.rs b/src/test/ui/parser/issues/issue-10392.rs new file mode 100644 index 000000000..5b0c2fc2b --- /dev/null +++ b/src/test/ui/parser/issues/issue-10392.rs @@ -0,0 +1,7 @@ +struct A { foo: isize } + +fn a() -> A { panic!() } + +fn main() { + let A { , } = a(); //~ ERROR expected ident +} diff --git a/src/test/ui/parser/issues/issue-10392.stderr b/src/test/ui/parser/issues/issue-10392.stderr new file mode 100644 index 000000000..438ea67d3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-10392.stderr @@ -0,0 +1,10 @@ +error: expected identifier, found `,` + --> $DIR/issue-10392.rs:6:13 + | +LL | let A { , } = a(); + | - ^ expected identifier + | | + | while parsing the fields for this pattern + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-10636-1.rs b/src/test/ui/parser/issues/issue-10636-1.rs new file mode 100644 index 000000000..77c6072d6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-10636-1.rs @@ -0,0 +1,8 @@ +struct Obj { + //~^ NOTE: unclosed delimiter + member: usize +) +//~^ ERROR mismatched closing delimiter +//~| NOTE mismatched closing delimiter + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-10636-1.stderr b/src/test/ui/parser/issues/issue-10636-1.stderr new file mode 100644 index 000000000..1e6294ebe --- /dev/null +++ b/src/test/ui/parser/issues/issue-10636-1.stderr @@ -0,0 +1,11 @@ +error: mismatched closing delimiter: `)` + --> $DIR/issue-10636-1.rs:1:12 + | +LL | struct Obj { + | ^ unclosed delimiter +... +LL | ) + | ^ mismatched closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-10636-2.rs b/src/test/ui/parser/issues/issue-10636-2.rs new file mode 100644 index 000000000..6fb63639d --- /dev/null +++ b/src/test/ui/parser/issues/issue-10636-2.rs @@ -0,0 +1,11 @@ +// FIXME(31528) we emit a bunch of silly errors here due to continuing past the +// first one. This would be easy-ish to address by better recovery in tokenisation. + +pub fn trace_option(option: Option<isize>) { + option.map(|some| 42; + //~^ ERROR: expected one of + +} +//~^ ERROR: expected expression, found `)` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-10636-2.stderr b/src/test/ui/parser/issues/issue-10636-2.stderr new file mode 100644 index 000000000..d4f2da9e3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-10636-2.stderr @@ -0,0 +1,16 @@ +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` + --> $DIR/issue-10636-2.rs:5:15 + | +LL | option.map(|some| 42; + | ^ ^ help: `)` may belong here + | | + | unclosed delimiter + +error: expected expression, found `)` + --> $DIR/issue-10636-2.rs:8:1 + | +LL | } + | ^ expected expression + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-13483.rs b/src/test/ui/parser/issues/issue-13483.rs new file mode 100644 index 000000000..4e32fcab3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-13483.rs @@ -0,0 +1,17 @@ +fn main() { + if true { + } else if { + //~^ ERROR missing condition for `if` expression + } else { + } +} + +fn foo() { + if true { + } else if { + //~^ ERROR missing condition for `if` expression + } + bar(); +} + +fn bar() {} diff --git a/src/test/ui/parser/issues/issue-13483.stderr b/src/test/ui/parser/issues/issue-13483.stderr new file mode 100644 index 000000000..f5534090f --- /dev/null +++ b/src/test/ui/parser/issues/issue-13483.stderr @@ -0,0 +1,18 @@ +error: missing condition for `if` expression + --> $DIR/issue-13483.rs:3:14 + | +LL | } else if { + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: missing condition for `if` expression + --> $DIR/issue-13483.rs:11:14 + | +LL | } else if { + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-14303-enum.rs b/src/test/ui/parser/issues/issue-14303-enum.rs new file mode 100644 index 000000000..a61061598 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-enum.rs @@ -0,0 +1,6 @@ +enum X<'a, T, 'b> { +//~^ ERROR lifetime parameters must be declared prior to type parameters + A(&'a &'b T) +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-enum.stderr b/src/test/ui/parser/issues/issue-14303-enum.stderr new file mode 100644 index 000000000..55cef4cab --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-enum.stderr @@ -0,0 +1,8 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/issue-14303-enum.rs:1:15 + | +LL | enum X<'a, T, 'b> { + | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-14303-fn-def.rs b/src/test/ui/parser/issues/issue-14303-fn-def.rs new file mode 100644 index 000000000..221bd311e --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-fn-def.rs @@ -0,0 +1,4 @@ +fn foo<'a, T, 'b>(x: &'a T) {} +//~^ ERROR lifetime parameters must be declared prior to type parameters + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-fn-def.stderr b/src/test/ui/parser/issues/issue-14303-fn-def.stderr new file mode 100644 index 000000000..bacc92296 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-fn-def.stderr @@ -0,0 +1,8 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/issue-14303-fn-def.rs:1:15 + | +LL | fn foo<'a, T, 'b>(x: &'a T) {} + | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-14303-fncall.full.stderr b/src/test/ui/parser/issues/issue-14303-fncall.full.stderr new file mode 100644 index 000000000..0c152516a --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-fncall.full.stderr @@ -0,0 +1,9 @@ +error[E0747]: type provided when a lifetime was expected + --> $DIR/issue-14303-fncall.rs:15:26 + | +LL | .collect::<Vec<S<_, 'a>>>(); + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr b/src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr new file mode 100644 index 000000000..571815776 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr @@ -0,0 +1,9 @@ +error[E0747]: inferred provided when a lifetime was expected + --> $DIR/issue-14303-fncall.rs:15:26 + | +LL | .collect::<Vec<S<_, 'a>>>(); + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/parser/issues/issue-14303-fncall.rs b/src/test/ui/parser/issues/issue-14303-fncall.rs new file mode 100644 index 000000000..afc4959f1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-fncall.rs @@ -0,0 +1,20 @@ +// revisions: full generic_arg +// can't run rustfix because it doesn't handle multipart suggestions correctly +// we need the above to avoid ast borrowck failure in recovered code +#![cfg_attr(generic_arg, feature(generic_arg_infer))] + + +struct S<'a, T> { + a: &'a T, + b: &'a T, +} + +fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { + let _x = (*start..*end) + .map(|x| S { a: start, b: end }) + .collect::<Vec<S<_, 'a>>>(); + //[generic_arg]~^ ERROR inferred provided when a lifetime was expected + //[full]~^^ ERROR type provided when a lifetime was expected +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-impl.rs b/src/test/ui/parser/issues/issue-14303-impl.rs new file mode 100644 index 000000000..4dc2c6660 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-impl.rs @@ -0,0 +1,6 @@ +struct X<T>(T); + +impl<'a, T, 'b> X<T> {} +//~^ ERROR lifetime parameters must be declared prior to type parameters + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-impl.stderr b/src/test/ui/parser/issues/issue-14303-impl.stderr new file mode 100644 index 000000000..d6be02f70 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-impl.stderr @@ -0,0 +1,8 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/issue-14303-impl.rs:3:13 + | +LL | impl<'a, T, 'b> X<T> {} + | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-14303-path.rs b/src/test/ui/parser/issues/issue-14303-path.rs new file mode 100644 index 000000000..89ef914ab --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-path.rs @@ -0,0 +1,13 @@ +mod foo { + pub struct X<'a, 'b, 'c, T> { + a: &'a str, + b: &'b str, + c: &'c str, + t: T, + } +} + +fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} +//~^ ERROR type provided when a lifetime was expected + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-path.stderr b/src/test/ui/parser/issues/issue-14303-path.stderr new file mode 100644 index 000000000..841e63ecb --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-path.stderr @@ -0,0 +1,9 @@ +error[E0747]: type provided when a lifetime was expected + --> $DIR/issue-14303-path.rs:10:37 + | +LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/parser/issues/issue-14303-struct.rs b/src/test/ui/parser/issues/issue-14303-struct.rs new file mode 100644 index 000000000..0bd10b4d0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-struct.rs @@ -0,0 +1,6 @@ +struct X<'a, T, 'b> { +//~^ ERROR lifetime parameters must be declared prior to type parameters + x: &'a &'b T +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-struct.stderr b/src/test/ui/parser/issues/issue-14303-struct.stderr new file mode 100644 index 000000000..fa62a39f2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-struct.stderr @@ -0,0 +1,8 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/issue-14303-struct.rs:1:17 + | +LL | struct X<'a, T, 'b> { + | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-14303-trait.rs b/src/test/ui/parser/issues/issue-14303-trait.rs new file mode 100644 index 000000000..f253de92d --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-trait.rs @@ -0,0 +1,4 @@ +trait Foo<'a, T, 'b> {} +//~^ ERROR lifetime parameters must be declared prior to type parameters + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-14303-trait.stderr b/src/test/ui/parser/issues/issue-14303-trait.stderr new file mode 100644 index 000000000..75cd67a9d --- /dev/null +++ b/src/test/ui/parser/issues/issue-14303-trait.stderr @@ -0,0 +1,8 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/issue-14303-trait.rs:1:18 + | +LL | trait Foo<'a, T, 'b> {} + | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-15914.rs b/src/test/ui/parser/issues/issue-15914.rs new file mode 100644 index 000000000..4a5606af6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-15914.rs @@ -0,0 +1,4 @@ +fn main() { + let ref + (); //~ ERROR expected identifier, found `(` +} diff --git a/src/test/ui/parser/issues/issue-15914.stderr b/src/test/ui/parser/issues/issue-15914.stderr new file mode 100644 index 000000000..ea26453f8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-15914.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `(` + --> $DIR/issue-15914.rs:3:9 + | +LL | (); + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-15980.rs b/src/test/ui/parser/issues/issue-15980.rs new file mode 100644 index 000000000..87faa7d5f --- /dev/null +++ b/src/test/ui/parser/issues/issue-15980.rs @@ -0,0 +1,17 @@ +use std::io; + +fn main(){ + let x: io::Result<()> = Ok(()); + match x { + Err(ref e) if e.kind == io::EndOfFile { + //~^ NOTE while parsing this struct + return + //~^ ERROR expected identifier, found keyword `return` + //~| NOTE expected identifier, found keyword + } + //~^ NOTE expected one of `.`, `=>`, `?`, or an operator + _ => {} + //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` + //~| NOTE unexpected token + } +} diff --git a/src/test/ui/parser/issues/issue-15980.stderr b/src/test/ui/parser/issues/issue-15980.stderr new file mode 100644 index 000000000..c59c81119 --- /dev/null +++ b/src/test/ui/parser/issues/issue-15980.stderr @@ -0,0 +1,25 @@ +error: expected identifier, found keyword `return` + --> $DIR/issue-15980.rs:8:13 + | +LL | Err(ref e) if e.kind == io::EndOfFile { + | ------------- while parsing this struct +LL | +LL | return + | ^^^^^^ expected identifier, found keyword + | +help: escape `return` to use it as an identifier + | +LL | r#return + | ++ + +error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` + --> $DIR/issue-15980.rs:13:9 + | +LL | } + | - expected one of `.`, `=>`, `?`, or an operator +LL | +LL | _ => {} + | ^ unexpected token + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-1655.rs b/src/test/ui/parser/issues/issue-1655.rs new file mode 100644 index 000000000..e9fc6f153 --- /dev/null +++ b/src/test/ui/parser/issues/issue-1655.rs @@ -0,0 +1,10 @@ +mod blade_runner { + #vec[doc( //~ ERROR expected one of `!` or `[`, found `vec` + brief = "Blade Runner is probably the best movie ever", + desc = "I like that in the world of Blade Runner it is always + raining, and that it's always night time. And Aliens + was also a really good movie. + + Alien 3 was crap though." + )] +} diff --git a/src/test/ui/parser/issues/issue-1655.stderr b/src/test/ui/parser/issues/issue-1655.stderr new file mode 100644 index 000000000..0c390a0ec --- /dev/null +++ b/src/test/ui/parser/issues/issue-1655.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `[`, found `vec` + --> $DIR/issue-1655.rs:2:6 + | +LL | #vec[doc( + | ^^^ expected one of `!` or `[` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-17383.rs b/src/test/ui/parser/issues/issue-17383.rs new file mode 100644 index 000000000..7bf0e64f2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-17383.rs @@ -0,0 +1,7 @@ +enum X { + A = 3, + //~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants + B(usize) +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-17383.stderr b/src/test/ui/parser/issues/issue-17383.stderr new file mode 100644 index 000000000..265d6e148 --- /dev/null +++ b/src/test/ui/parser/issues/issue-17383.stderr @@ -0,0 +1,15 @@ +error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants + --> $DIR/issue-17383.rs:2:9 + | +LL | A = 3, + | ^ disallowed custom discriminant +LL | +LL | B(usize) + | -------- tuple variant defined here + | + = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/parser/issues/issue-17718-const-mut.rs b/src/test/ui/parser/issues/issue-17718-const-mut.rs new file mode 100644 index 000000000..795a8c763 --- /dev/null +++ b/src/test/ui/parser/issues/issue-17718-const-mut.rs @@ -0,0 +1,7 @@ +const +mut //~ ERROR: const globals cannot be mutable +//~^^ HELP you might want to declare a static instead +FOO: usize = 3; + +fn main() { +} diff --git a/src/test/ui/parser/issues/issue-17718-const-mut.stderr b/src/test/ui/parser/issues/issue-17718-const-mut.stderr new file mode 100644 index 000000000..8251ce999 --- /dev/null +++ b/src/test/ui/parser/issues/issue-17718-const-mut.stderr @@ -0,0 +1,10 @@ +error: const globals cannot be mutable + --> $DIR/issue-17718-const-mut.rs:2:1 + | +LL | const + | ----- help: you might want to declare a static instead: `static` +LL | mut + | ^^^ cannot be mutable + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-17904-2.rs b/src/test/ui/parser/issues/issue-17904-2.rs new file mode 100644 index 000000000..186a955c3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-17904-2.rs @@ -0,0 +1,3 @@ +struct Bar<T> { x: T } where T: Copy //~ ERROR expected item, found keyword `where` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-17904-2.stderr b/src/test/ui/parser/issues/issue-17904-2.stderr new file mode 100644 index 000000000..9c7fdf6cc --- /dev/null +++ b/src/test/ui/parser/issues/issue-17904-2.stderr @@ -0,0 +1,8 @@ +error: expected item, found keyword `where` + --> $DIR/issue-17904-2.rs:1:24 + | +LL | struct Bar<T> { x: T } where T: Copy + | ^^^^^ expected item + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-17904.rs b/src/test/ui/parser/issues/issue-17904.rs new file mode 100644 index 000000000..7d6a54f4b --- /dev/null +++ b/src/test/ui/parser/issues/issue-17904.rs @@ -0,0 +1,6 @@ +struct Baz<U> where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax. +struct Baz<U> where U: Eq(U) -> R; // Notice this parses as well. +struct Baz<U>(U) where U: Eq; // This rightfully signals no error as well. +struct Foo<T> where T: Copy, (T); //~ ERROR expected one of `:`, `==`, or `=`, found `;` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-17904.stderr b/src/test/ui/parser/issues/issue-17904.stderr new file mode 100644 index 000000000..a3cac6761 --- /dev/null +++ b/src/test/ui/parser/issues/issue-17904.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `==`, or `=`, found `;` + --> $DIR/issue-17904.rs:4:33 + | +LL | struct Foo<T> where T: Copy, (T); + | ^ expected one of `:`, `==`, or `=` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-1802-1.rs b/src/test/ui/parser/issues/issue-1802-1.rs new file mode 100644 index 000000000..3c34b0d8f --- /dev/null +++ b/src/test/ui/parser/issues/issue-1802-1.rs @@ -0,0 +1,7 @@ +fn log(a: i32, b: i32) {} + +fn main() { + let error = 42; + log(error, 0b); + //~^ ERROR no valid digits found for number +} diff --git a/src/test/ui/parser/issues/issue-1802-1.stderr b/src/test/ui/parser/issues/issue-1802-1.stderr new file mode 100644 index 000000000..954cc0bee --- /dev/null +++ b/src/test/ui/parser/issues/issue-1802-1.stderr @@ -0,0 +1,9 @@ +error[E0768]: no valid digits found for number + --> $DIR/issue-1802-1.rs:5:16 + | +LL | log(error, 0b); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0768`. diff --git a/src/test/ui/parser/issues/issue-1802-2.rs b/src/test/ui/parser/issues/issue-1802-2.rs new file mode 100644 index 000000000..3c34b0d8f --- /dev/null +++ b/src/test/ui/parser/issues/issue-1802-2.rs @@ -0,0 +1,7 @@ +fn log(a: i32, b: i32) {} + +fn main() { + let error = 42; + log(error, 0b); + //~^ ERROR no valid digits found for number +} diff --git a/src/test/ui/parser/issues/issue-1802-2.stderr b/src/test/ui/parser/issues/issue-1802-2.stderr new file mode 100644 index 000000000..49043d07b --- /dev/null +++ b/src/test/ui/parser/issues/issue-1802-2.stderr @@ -0,0 +1,9 @@ +error[E0768]: no valid digits found for number + --> $DIR/issue-1802-2.rs:5:16 + | +LL | log(error, 0b); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0768`. diff --git a/src/test/ui/parser/issues/issue-19096.rs b/src/test/ui/parser/issues/issue-19096.rs new file mode 100644 index 000000000..c5bfd10ee --- /dev/null +++ b/src/test/ui/parser/issues/issue-19096.rs @@ -0,0 +1,10 @@ +fn main() { // we don't complain about the return type being `{integer}` + let t = (42, 42); + t.0::<isize>; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `::` +} + +fn foo() -> usize { // we don't complain about the return type being unit + let t = (42, 42); + t.0::<isize>; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `::` + 42; +} diff --git a/src/test/ui/parser/issues/issue-19096.stderr b/src/test/ui/parser/issues/issue-19096.stderr new file mode 100644 index 000000000..4df7f878b --- /dev/null +++ b/src/test/ui/parser/issues/issue-19096.stderr @@ -0,0 +1,14 @@ +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::` + --> $DIR/issue-19096.rs:3:8 + | +LL | t.0::<isize>; + | ^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::` + --> $DIR/issue-19096.rs:8:8 + | +LL | t.0::<isize>; + | ^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-19398.rs b/src/test/ui/parser/issues/issue-19398.rs new file mode 100644 index 000000000..46eb320a1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-19398.rs @@ -0,0 +1,6 @@ +trait T { + extern "Rust" unsafe fn foo(); + //~^ ERROR expected `{`, found keyword `unsafe` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-19398.stderr b/src/test/ui/parser/issues/issue-19398.stderr new file mode 100644 index 000000000..1da00960a --- /dev/null +++ b/src/test/ui/parser/issues/issue-19398.stderr @@ -0,0 +1,13 @@ +error: expected `{`, found keyword `unsafe` + --> $DIR/issue-19398.rs:2:19 + | +LL | trait T { + | - while parsing this item list starting here +LL | extern "Rust" unsafe fn foo(); + | ^^^^^^ expected `{` +LL | +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-1.rs b/src/test/ui/parser/issues/issue-20616-1.rs new file mode 100644 index 000000000..49e9cb310 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-1.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + + + +type Type_1_<'a, T> = &'a T; + + +type Type_1<'a T> = &'a T; //~ error: expected one of `,`, `:`, or `>`, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-1.stderr b/src/test/ui/parser/issues/issue-20616-1.stderr new file mode 100644 index 000000000..816046237 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-1.stderr @@ -0,0 +1,8 @@ +error: expected one of `,`, `:`, or `>`, found `T` + --> $DIR/issue-20616-1.rs:9:16 + | +LL | type Type_1<'a T> = &'a T; + | ^ expected one of `,`, `:`, or `>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-2.rs b/src/test/ui/parser/issues/issue-20616-2.rs new file mode 100644 index 000000000..2f2c6903a --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-2.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + + + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +type Type_2 = Type_1_<'static ()>; //~ error: expected one of `,` or `>`, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-2.stderr b/src/test/ui/parser/issues/issue-20616-2.stderr new file mode 100644 index 000000000..42059685c --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-2.stderr @@ -0,0 +1,13 @@ +error: expected one of `,` or `>`, found `(` + --> $DIR/issue-20616-2.rs:12:31 + | +LL | type Type_2 = Type_1_<'static ()>; + | ^ expected one of `,` or `>` + | +help: you might have meant to end the type parameters here + | +LL | type Type_2 = Type_1_<'static> ()>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-3.rs b/src/test/ui/parser/issues/issue-20616-3.rs new file mode 100644 index 000000000..b2371051c --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-3.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +type Type_3<T> = Box<T,,>; +//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-3.stderr b/src/test/ui/parser/issues/issue-20616-3.stderr new file mode 100644 index 000000000..dbff116e5 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-3.stderr @@ -0,0 +1,13 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `,` + --> $DIR/issue-20616-3.rs:13:24 + | +LL | type Type_3<T> = Box<T,,>; + | ^ expected one of `>`, a const expression, lifetime, or type + | +help: you might have meant to end the type parameters here + | +LL | type Type_3<T> = Box<T>,,>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-4.rs b/src/test/ui/parser/issues/issue-20616-4.rs new file mode 100644 index 000000000..a71f47ca4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-4.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +type Type_4<T> = Type_1_<'static,, T>; +//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-4.stderr b/src/test/ui/parser/issues/issue-20616-4.stderr new file mode 100644 index 000000000..48a06e00b --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-4.stderr @@ -0,0 +1,13 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `,` + --> $DIR/issue-20616-4.rs:16:34 + | +LL | type Type_4<T> = Type_1_<'static,, T>; + | ^ expected one of `>`, a const expression, lifetime, or type + | +help: you might have meant to end the type parameters here + | +LL | type Type_4<T> = Type_1_<'static>,, T>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-5.rs b/src/test/ui/parser/issues/issue-20616-5.rs new file mode 100644 index 000000000..b96d09d59 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-5.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +type Type_5<'a> = Type_1_<'a, (),,>; +//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-5.stderr b/src/test/ui/parser/issues/issue-20616-5.stderr new file mode 100644 index 000000000..84bee2ad1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-5.stderr @@ -0,0 +1,13 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `,` + --> $DIR/issue-20616-5.rs:22:34 + | +LL | type Type_5<'a> = Type_1_<'a, (),,>; + | ^ expected one of `>`, a const expression, lifetime, or type + | +help: you might have meant to end the type parameters here + | +LL | type Type_5<'a> = Type_1_<'a, ()>,,>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-6.rs b/src/test/ui/parser/issues/issue-20616-6.rs new file mode 100644 index 000000000..a2c45ecec --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-6.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +type Type_6 = Type_5_<'a,,>; +//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-6.stderr b/src/test/ui/parser/issues/issue-20616-6.stderr new file mode 100644 index 000000000..67de41b97 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-6.stderr @@ -0,0 +1,13 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `,` + --> $DIR/issue-20616-6.rs:25:26 + | +LL | type Type_6 = Type_5_<'a,,>; + | ^ expected one of `>`, a const expression, lifetime, or type + | +help: you might have meant to end the type parameters here + | +LL | type Type_6 = Type_5_<'a>,,>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-7.rs b/src/test/ui/parser/issues/issue-20616-7.rs new file mode 100644 index 000000000..67209c02a --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-7.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +type Type_7 = Box<(),,>; +//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected ident, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-7.stderr b/src/test/ui/parser/issues/issue-20616-7.stderr new file mode 100644 index 000000000..3b8e07fa0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-7.stderr @@ -0,0 +1,13 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `,` + --> $DIR/issue-20616-7.rs:28:22 + | +LL | type Type_7 = Box<(),,>; + | ^ expected one of `>`, a const expression, lifetime, or type + | +help: you might have meant to end the type parameters here + | +LL | type Type_7 = Box<()>,,>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-8.rs b/src/test/ui/parser/issues/issue-20616-8.rs new file mode 100644 index 000000000..3ceb58d12 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-8.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +type Type_8<'a,,> = &'a (); +//~^ error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,` + + +//type Type_9<T,,> = Box<T>; // error: expected identifier, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-8.stderr b/src/test/ui/parser/issues/issue-20616-8.stderr new file mode 100644 index 000000000..e9f37e50f --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-8.stderr @@ -0,0 +1,8 @@ +error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,` + --> $DIR/issue-20616-8.rs:31:16 + | +LL | type Type_8<'a,,> = &'a (); + | ^ expected one of `#`, `>`, `const`, identifier, or lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20616-9.rs b/src/test/ui/parser/issues/issue-20616-9.rs new file mode 100644 index 000000000..7f8428448 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-9.rs @@ -0,0 +1,35 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3<T> = Box<T,,>; // error: expected type, found `,` + + +//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected identifier, found `,` + + +type Type_9<T,,> = Box<T>; +//~^ error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,` diff --git a/src/test/ui/parser/issues/issue-20616-9.stderr b/src/test/ui/parser/issues/issue-20616-9.stderr new file mode 100644 index 000000000..dc309d1bc --- /dev/null +++ b/src/test/ui/parser/issues/issue-20616-9.stderr @@ -0,0 +1,8 @@ +error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,` + --> $DIR/issue-20616-9.rs:34:15 + | +LL | type Type_9<T,,> = Box<T>; + | ^ expected one of `#`, `>`, `const`, identifier, or lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20711-2.rs b/src/test/ui/parser/issues/issue-20711-2.rs new file mode 100644 index 000000000..168c7e761 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20711-2.rs @@ -0,0 +1,10 @@ +struct Foo; + +impl Foo { + fn foo() {} + + #[stable(feature = "rust1", since = "1.0.0")] + //~^ ERROR expected item after attributes +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-20711-2.stderr b/src/test/ui/parser/issues/issue-20711-2.stderr new file mode 100644 index 000000000..12b18bbc5 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20711-2.stderr @@ -0,0 +1,14 @@ +error: expected item after attributes + --> $DIR/issue-20711-2.rs:6:5 + | +LL | impl Foo { + | - while parsing this item list starting here +... +LL | #[stable(feature = "rust1", since = "1.0.0")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-20711.rs b/src/test/ui/parser/issues/issue-20711.rs new file mode 100644 index 000000000..020bb79d6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-20711.rs @@ -0,0 +1,8 @@ +struct Foo; + +impl Foo { + #[stable(feature = "rust1", since = "1.0.0")] + //~^ ERROR expected item after attributes +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-20711.stderr b/src/test/ui/parser/issues/issue-20711.stderr new file mode 100644 index 000000000..4af4b22be --- /dev/null +++ b/src/test/ui/parser/issues/issue-20711.stderr @@ -0,0 +1,13 @@ +error: expected item after attributes + --> $DIR/issue-20711.rs:4:5 + | +LL | impl Foo { + | - while parsing this item list starting here +LL | #[stable(feature = "rust1", since = "1.0.0")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-21146.rs b/src/test/ui/parser/issues/issue-21146.rs new file mode 100644 index 000000000..19eaffc3e --- /dev/null +++ b/src/test/ui/parser/issues/issue-21146.rs @@ -0,0 +1,3 @@ +// error-pattern: expected one of `!` or `::`, found `<eof>` +include!("auxiliary/issue-21146-inc.rs"); +fn main() {} diff --git a/src/test/ui/parser/issues/issue-21146.stderr b/src/test/ui/parser/issues/issue-21146.stderr new file mode 100644 index 000000000..c71fda3d6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-21146.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `::`, found `<eof>` + --> $DIR/auxiliary/issue-21146-inc.rs:3:1 + | +LL | parse_error + | ^^^^^^^^^^^ expected one of `!` or `::` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-21153.rs b/src/test/ui/parser/issues/issue-21153.rs new file mode 100644 index 000000000..bf5fdb1f3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-21153.rs @@ -0,0 +1,6 @@ +trait MyTrait<T>: Iterator { + Item = T; + //~^ ERROR expected one of `!` or `::`, found `=` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-21153.stderr b/src/test/ui/parser/issues/issue-21153.stderr new file mode 100644 index 000000000..cbfa9ded3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-21153.stderr @@ -0,0 +1,13 @@ +error: expected one of `!` or `::`, found `=` + --> $DIR/issue-21153.rs:2:10 + | +LL | trait MyTrait<T>: Iterator { + | - while parsing this item list starting here +LL | Item = T; + | ^ expected one of `!` or `::` +LL | +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-21475.rs b/src/test/ui/parser/issues/issue-21475.rs new file mode 100644 index 000000000..b028fcae0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-21475.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_imports, overlapping_range_endpoints)] +// pretty-expanded FIXME #23616 + +use m::{START, END}; + +fn main() { + match 42 { + m::START..=m::END => {}, + 0..=m::END => {}, + m::START..=59 => {}, + _ => {}, + } +} + +mod m { + pub const START: u32 = 4; + pub const END: u32 = 14; +} diff --git a/src/test/ui/parser/issues/issue-22647.rs b/src/test/ui/parser/issues/issue-22647.rs new file mode 100644 index 000000000..a68614106 --- /dev/null +++ b/src/test/ui/parser/issues/issue-22647.rs @@ -0,0 +1,15 @@ +fn main() { + let caller<F> = |f: F| //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<` + where F: Fn() -> i32 + { + let x = f(); + println!("Y {}",x); + return x; + }; + + caller(bar_handler); +} + +fn bar_handler() -> i32 { + 5 +} diff --git a/src/test/ui/parser/issues/issue-22647.stderr b/src/test/ui/parser/issues/issue-22647.stderr new file mode 100644 index 000000000..89b454d19 --- /dev/null +++ b/src/test/ui/parser/issues/issue-22647.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<` + --> $DIR/issue-22647.rs:2:15 + | +LL | let caller<F> = |f: F| + | ^ expected one of `:`, `;`, `=`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-22712.rs b/src/test/ui/parser/issues/issue-22712.rs new file mode 100644 index 000000000..774de9c7e --- /dev/null +++ b/src/test/ui/parser/issues/issue-22712.rs @@ -0,0 +1,9 @@ +struct Foo<B> { + buffer: B +} + +fn bar() { + let Foo<Vec<u8>> //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-22712.stderr b/src/test/ui/parser/issues/issue-22712.stderr new file mode 100644 index 000000000..30fabac65 --- /dev/null +++ b/src/test/ui/parser/issues/issue-22712.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<` + --> $DIR/issue-22712.rs:6:12 + | +LL | let Foo<Vec<u8>> + | ^ expected one of `:`, `;`, `=`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-2354-1.rs b/src/test/ui/parser/issues/issue-2354-1.rs new file mode 100644 index 000000000..996cf1bcb --- /dev/null +++ b/src/test/ui/parser/issues/issue-2354-1.rs @@ -0,0 +1 @@ +static foo: isize = 2; } //~ ERROR unexpected closing delimiter: diff --git a/src/test/ui/parser/issues/issue-2354-1.stderr b/src/test/ui/parser/issues/issue-2354-1.stderr new file mode 100644 index 000000000..7ea0f2a98 --- /dev/null +++ b/src/test/ui/parser/issues/issue-2354-1.stderr @@ -0,0 +1,8 @@ +error: unexpected closing delimiter: `}` + --> $DIR/issue-2354-1.rs:1:24 + | +LL | static foo: isize = 2; } + | ^ unexpected closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-2354.rs b/src/test/ui/parser/issues/issue-2354.rs new file mode 100644 index 000000000..c422040cb --- /dev/null +++ b/src/test/ui/parser/issues/issue-2354.rs @@ -0,0 +1,15 @@ +fn foo() { //~ NOTE unclosed delimiter + match Some(10) { + //~^ NOTE this delimiter might not be properly closed... + Some(y) => { panic!(); } + None => { panic!(); } +} +//~^ NOTE ...as it matches this but it has different indentation + +fn bar() { + let mut i = 0; + while (i < 1000) {} +} + +fn main() {} +//~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/issues/issue-2354.stderr b/src/test/ui/parser/issues/issue-2354.stderr new file mode 100644 index 000000000..b89ed3958 --- /dev/null +++ b/src/test/ui/parser/issues/issue-2354.stderr @@ -0,0 +1,16 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-2354.rs:15:52 + | +LL | fn foo() { + | - unclosed delimiter +LL | match Some(10) { + | - this delimiter might not be properly closed... +... +LL | } + | - ...as it matches this but it has different indentation +... +LL | + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-23620-invalid-escapes.rs b/src/test/ui/parser/issues/issue-23620-invalid-escapes.rs new file mode 100644 index 000000000..c1355f0d6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-23620-invalid-escapes.rs @@ -0,0 +1,34 @@ +fn main() { + let _ = b"\u{a66e}"; + //~^ ERROR unicode escape in byte string + + let _ = b'\u{a66e}'; + //~^ ERROR unicode escape in byte string + + let _ = b'\u'; + //~^ ERROR incorrect unicode escape sequence + + let _ = b'\x5'; + //~^ ERROR numeric character escape is too short + + let _ = b'\xxy'; + //~^ ERROR invalid character in numeric character escape: `x` + + let _ = '\x5'; + //~^ ERROR numeric character escape is too short + + let _ = '\xxy'; + //~^ ERROR invalid character in numeric character escape: `x` + + let _ = b"\u{a4a4} \xf \u"; + //~^ ERROR unicode escape in byte string + //~^^ ERROR invalid character in numeric character escape: ` ` + //~^^^ ERROR incorrect unicode escape sequence + + let _ = "\xf \u"; + //~^ ERROR invalid character in numeric character escape: ` ` + //~^^ ERROR incorrect unicode escape sequence + + let _ = "\u8f"; + //~^ ERROR incorrect unicode escape sequence +} diff --git a/src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr new file mode 100644 index 000000000..88d97c795 --- /dev/null +++ b/src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr @@ -0,0 +1,94 @@ +error: unicode escape in byte string + --> $DIR/issue-23620-invalid-escapes.rs:2:15 + | +LL | let _ = b"\u{a66e}"; + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string + +error: unicode escape in byte string + --> $DIR/issue-23620-invalid-escapes.rs:5:15 + | +LL | let _ = b'\u{a66e}'; + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string + +error: incorrect unicode escape sequence + --> $DIR/issue-23620-invalid-escapes.rs:8:15 + | +LL | let _ = b'\u'; + | ^^ incorrect unicode escape sequence + | + = help: format of unicode escape sequences is `\u{...}` + +error: numeric character escape is too short + --> $DIR/issue-23620-invalid-escapes.rs:11:15 + | +LL | let _ = b'\x5'; + | ^^^ + +error: invalid character in numeric character escape: `x` + --> $DIR/issue-23620-invalid-escapes.rs:14:17 + | +LL | let _ = b'\xxy'; + | ^ invalid character in numeric character escape + +error: numeric character escape is too short + --> $DIR/issue-23620-invalid-escapes.rs:17:14 + | +LL | let _ = '\x5'; + | ^^^ + +error: invalid character in numeric character escape: `x` + --> $DIR/issue-23620-invalid-escapes.rs:20:16 + | +LL | let _ = '\xxy'; + | ^ invalid character in numeric character escape + +error: unicode escape in byte string + --> $DIR/issue-23620-invalid-escapes.rs:23:15 + | +LL | let _ = b"\u{a4a4} \xf \u"; + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string + +error: invalid character in numeric character escape: ` ` + --> $DIR/issue-23620-invalid-escapes.rs:23:27 + | +LL | let _ = b"\u{a4a4} \xf \u"; + | ^ invalid character in numeric character escape + +error: incorrect unicode escape sequence + --> $DIR/issue-23620-invalid-escapes.rs:23:28 + | +LL | let _ = b"\u{a4a4} \xf \u"; + | ^^ incorrect unicode escape sequence + | + = help: format of unicode escape sequences is `\u{...}` + +error: invalid character in numeric character escape: ` ` + --> $DIR/issue-23620-invalid-escapes.rs:28:17 + | +LL | let _ = "\xf \u"; + | ^ invalid character in numeric character escape + +error: incorrect unicode escape sequence + --> $DIR/issue-23620-invalid-escapes.rs:28:18 + | +LL | let _ = "\xf \u"; + | ^^ incorrect unicode escape sequence + | + = help: format of unicode escape sequences is `\u{...}` + +error: incorrect unicode escape sequence + --> $DIR/issue-23620-invalid-escapes.rs:32:14 + | +LL | let _ = "\u8f"; + | ^^^- + | | + | help: format of unicode escape sequences uses braces: `\u{8f}` + +error: aborting due to 13 previous errors + diff --git a/src/test/ui/parser/issues/issue-24197.rs b/src/test/ui/parser/issues/issue-24197.rs new file mode 100644 index 000000000..aaf513746 --- /dev/null +++ b/src/test/ui/parser/issues/issue-24197.rs @@ -0,0 +1,3 @@ +fn main() { + let buf[0] = 0; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[` +} diff --git a/src/test/ui/parser/issues/issue-24197.stderr b/src/test/ui/parser/issues/issue-24197.stderr new file mode 100644 index 000000000..fd7015ccd --- /dev/null +++ b/src/test/ui/parser/issues/issue-24197.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` + --> $DIR/issue-24197.rs:2:12 + | +LL | let buf[0] = 0; + | ^ expected one of `:`, `;`, `=`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-24375.rs b/src/test/ui/parser/issues/issue-24375.rs new file mode 100644 index 000000000..1d128d33e --- /dev/null +++ b/src/test/ui/parser/issues/issue-24375.rs @@ -0,0 +1,9 @@ +static tmp : [&'static str; 2] = ["hello", "he"]; + +fn main() { + let z = "hello"; + match z { + tmp[0] => {} //~ ERROR expected one of `=>`, `@`, `if`, or `|`, found `[` + _ => {} + } +} diff --git a/src/test/ui/parser/issues/issue-24375.stderr b/src/test/ui/parser/issues/issue-24375.stderr new file mode 100644 index 000000000..7aed88768 --- /dev/null +++ b/src/test/ui/parser/issues/issue-24375.stderr @@ -0,0 +1,8 @@ +error: expected one of `=>`, `@`, `if`, or `|`, found `[` + --> $DIR/issue-24375.rs:6:12 + | +LL | tmp[0] => {} + | ^ expected one of `=>`, `@`, `if`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-24780.rs b/src/test/ui/parser/issues/issue-24780.rs new file mode 100644 index 000000000..017521f57 --- /dev/null +++ b/src/test/ui/parser/issues/issue-24780.rs @@ -0,0 +1,9 @@ +// Verify that '>' is not both expected and found at the same time, as it used +// to happen in #24780. For example, following should be an error: +// expected one of ..., `>`, ... found `>`. + +fn foo() -> Vec<usize>> { //~ ERROR expected one of `!`, `+`, `::`, `where`, or `{`, found `>` + Vec::new() +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-24780.stderr b/src/test/ui/parser/issues/issue-24780.stderr new file mode 100644 index 000000000..d9470191b --- /dev/null +++ b/src/test/ui/parser/issues/issue-24780.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `+`, `::`, `where`, or `{`, found `>` + --> $DIR/issue-24780.rs:5:23 + | +LL | fn foo() -> Vec<usize>> { + | ^ expected one of `!`, `+`, `::`, `where`, or `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-27255.rs b/src/test/ui/parser/issues/issue-27255.rs new file mode 100644 index 000000000..d619688e1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-27255.rs @@ -0,0 +1,10 @@ +trait A {} + +impl A .. {} +//~^ ERROR missing `for` in a trait impl +//~| ERROR `impl Trait for .. {}` is an obsolete syntax + +impl A usize {} +//~^ ERROR missing `for` in a trait impl + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-27255.stderr b/src/test/ui/parser/issues/issue-27255.stderr new file mode 100644 index 000000000..391a23556 --- /dev/null +++ b/src/test/ui/parser/issues/issue-27255.stderr @@ -0,0 +1,22 @@ +error: missing `for` in a trait impl + --> $DIR/issue-27255.rs:3:7 + | +LL | impl A .. {} + | ^ help: add `for` here + +error: missing `for` in a trait impl + --> $DIR/issue-27255.rs:7:7 + | +LL | impl A usize {} + | ^^^^^^ help: add `for` here + +error: `impl Trait for .. {}` is an obsolete syntax + --> $DIR/issue-27255.rs:3:1 + | +LL | impl A .. {} + | ^^^^^^^^^^^^ + | + = help: use `auto trait Trait {}` instead + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-30318.fixed b/src/test/ui/parser/issues/issue-30318.fixed new file mode 100644 index 000000000..71fc82172 --- /dev/null +++ b/src/test/ui/parser/issues/issue-30318.fixed @@ -0,0 +1,27 @@ +// run-rustfix +#![allow(unused)] +fn foo() { } + +/// Misplaced comment... +//~^ ERROR expected outer doc comment +fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function + +#[test] //~ ERROR an inner attribute is not permitted in this context +fn baz() { } //~ NOTE the inner attribute doesn't annotate this function +//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually + +/** Misplaced comment... */ +//~^ ERROR expected outer doc comment +fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function + +fn main() { } + +// Misplaced comment... +//~^ ERROR expected outer doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +//~| NOTE other attributes here +/* Misplaced comment... */ +//~^ ERROR expected outer doc comment +//~| NOTE this doc comment doesn't document anything +//~| ERROR expected item after doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items diff --git a/src/test/ui/parser/issues/issue-30318.rs b/src/test/ui/parser/issues/issue-30318.rs new file mode 100644 index 000000000..465dca2ff --- /dev/null +++ b/src/test/ui/parser/issues/issue-30318.rs @@ -0,0 +1,27 @@ +// run-rustfix +#![allow(unused)] +fn foo() { } + +//! Misplaced comment... +//~^ ERROR expected outer doc comment +fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function + +#![test] //~ ERROR an inner attribute is not permitted in this context +fn baz() { } //~ NOTE the inner attribute doesn't annotate this function +//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually + +/*! Misplaced comment... */ +//~^ ERROR expected outer doc comment +fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function + +fn main() { } + +//! Misplaced comment... +//~^ ERROR expected outer doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +//~| NOTE other attributes here +/*! Misplaced comment... */ +//~^ ERROR expected outer doc comment +//~| NOTE this doc comment doesn't document anything +//~| ERROR expected item after doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items diff --git a/src/test/ui/parser/issues/issue-30318.stderr b/src/test/ui/parser/issues/issue-30318.stderr new file mode 100644 index 000000000..c441a92ab --- /dev/null +++ b/src/test/ui/parser/issues/issue-30318.stderr @@ -0,0 +1,81 @@ +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:5:1 + | +LL | //! Misplaced comment... + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bar() { } + | ------------ the inner doc comment doesn't annotate this function + | +help: to annotate the function, change the doc comment from inner to outer style + | +LL | /// Misplaced comment... + | ~ + +error: an inner attribute is not permitted in this context + --> $DIR/issue-30318.rs:9:1 + | +LL | #![test] + | ^^^^^^^^ +LL | fn baz() { } + | ------------ the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![test] +LL + #[test] + | + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:13:1 + | +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bat() { } + | ------------ the inner doc comment doesn't annotate this function + | +help: to annotate the function, change the doc comment from inner to outer style + | +LL | /** Misplaced comment... */ + | ~ + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:19:1 + | +LL | //! Misplaced comment... + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - //! Misplaced comment... +LL + // Misplaced comment... + | + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:23:1 + | +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - /*! Misplaced comment... */ +LL + /* Misplaced comment... */ + | + +error: expected item after doc comment + --> $DIR/issue-30318.rs:23:1 + | +LL | //! Misplaced comment... + | ------------------------ other attributes here +... +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0753`. diff --git a/src/test/ui/parser/issues/issue-3036.fixed b/src/test/ui/parser/issues/issue-3036.fixed new file mode 100644 index 000000000..e5d5622e6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-3036.fixed @@ -0,0 +1,7 @@ +// run-rustfix + +// Testing that semicolon tokens are printed correctly in errors + +fn main() { + let _x = 3; //~ ERROR: expected `;` +} diff --git a/src/test/ui/parser/issues/issue-3036.rs b/src/test/ui/parser/issues/issue-3036.rs new file mode 100644 index 000000000..2f76fb99b --- /dev/null +++ b/src/test/ui/parser/issues/issue-3036.rs @@ -0,0 +1,7 @@ +// run-rustfix + +// Testing that semicolon tokens are printed correctly in errors + +fn main() { + let _x = 3 //~ ERROR: expected `;` +} diff --git a/src/test/ui/parser/issues/issue-3036.stderr b/src/test/ui/parser/issues/issue-3036.stderr new file mode 100644 index 000000000..e02223931 --- /dev/null +++ b/src/test/ui/parser/issues/issue-3036.stderr @@ -0,0 +1,10 @@ +error: expected `;`, found `}` + --> $DIR/issue-3036.rs:6:15 + | +LL | let _x = 3 + | ^ help: add `;` here +LL | } + | - unexpected token + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-31804.rs b/src/test/ui/parser/issues/issue-31804.rs new file mode 100644 index 000000000..d056b77cf --- /dev/null +++ b/src/test/ui/parser/issues/issue-31804.rs @@ -0,0 +1,6 @@ +// Test that error recovery in the parser to an EOF does not give an infinite +// spew of errors. + +fn main() { + let +} //~ ERROR expected pattern, found `}` diff --git a/src/test/ui/parser/issues/issue-31804.stderr b/src/test/ui/parser/issues/issue-31804.stderr new file mode 100644 index 000000000..76e68b0b3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-31804.stderr @@ -0,0 +1,8 @@ +error: expected pattern, found `}` + --> $DIR/issue-31804.rs:6:1 + | +LL | } + | ^ expected pattern + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-32214.rs b/src/test/ui/parser/issues/issue-32214.rs new file mode 100644 index 000000000..1379eeb58 --- /dev/null +++ b/src/test/ui/parser/issues/issue-32214.rs @@ -0,0 +1,6 @@ +trait Trait<T> { type Item; } + +pub fn test<W, I: Trait<Item=(), W> >() {} +//~^ ERROR generic arguments must come before the first constraint + +fn main() { } diff --git a/src/test/ui/parser/issues/issue-32214.stderr b/src/test/ui/parser/issues/issue-32214.stderr new file mode 100644 index 000000000..d0a9b5299 --- /dev/null +++ b/src/test/ui/parser/issues/issue-32214.stderr @@ -0,0 +1,15 @@ +error: generic arguments must come before the first constraint + --> $DIR/issue-32214.rs:3:34 + | +LL | pub fn test<W, I: Trait<Item=(), W> >() {} + | ------- ^ generic argument + | | + | constraint + | +help: move the constraint after the generic argument + | +LL | pub fn test<W, I: Trait<W, Item = ()> >() {} + | ~~~~~~~~~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-32446.rs b/src/test/ui/parser/issues/issue-32446.rs new file mode 100644 index 000000000..53e519a72 --- /dev/null +++ b/src/test/ui/parser/issues/issue-32446.rs @@ -0,0 +1,4 @@ +fn main() {} + +// This used to end up in an infite loop trying to bump past EOF. +trait T { ... } //~ ERROR diff --git a/src/test/ui/parser/issues/issue-32446.stderr b/src/test/ui/parser/issues/issue-32446.stderr new file mode 100644 index 000000000..7515369aa --- /dev/null +++ b/src/test/ui/parser/issues/issue-32446.stderr @@ -0,0 +1,11 @@ +error: non-item in item list + --> $DIR/issue-32446.rs:4:11 + | +LL | trait T { ... } + | - ^^^ - item list ends here + | | | + | | non-item starts here + | item list starts here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-32501.rs b/src/test/ui/parser/issues/issue-32501.rs new file mode 100644 index 000000000..500242030 --- /dev/null +++ b/src/test/ui/parser/issues/issue-32501.rs @@ -0,0 +1,9 @@ +fn main() { + let a = 0; + let _b = 0; + let _ = 0; + let mut b = 0; + let mut _b = 0; + let mut _ = 0; + //~^ ERROR `mut` must be followed by a named binding +} diff --git a/src/test/ui/parser/issues/issue-32501.stderr b/src/test/ui/parser/issues/issue-32501.stderr new file mode 100644 index 000000000..d53302449 --- /dev/null +++ b/src/test/ui/parser/issues/issue-32501.stderr @@ -0,0 +1,10 @@ +error: `mut` must be followed by a named binding + --> $DIR/issue-32501.rs:7:9 + | +LL | let mut _ = 0; + | ^^^^^ help: remove the `mut` prefix: `_` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-32505.rs b/src/test/ui/parser/issues/issue-32505.rs new file mode 100644 index 000000000..f31c00e5c --- /dev/null +++ b/src/test/ui/parser/issues/issue-32505.rs @@ -0,0 +1,5 @@ +pub fn test() { + foo(|_|) //~ ERROR expected expression, found `)` +} + +fn main() { } diff --git a/src/test/ui/parser/issues/issue-32505.stderr b/src/test/ui/parser/issues/issue-32505.stderr new file mode 100644 index 000000000..cdd779a93 --- /dev/null +++ b/src/test/ui/parser/issues/issue-32505.stderr @@ -0,0 +1,8 @@ +error: expected expression, found `)` + --> $DIR/issue-32505.rs:2:12 + | +LL | foo(|_|) + | ^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-33262.rs b/src/test/ui/parser/issues/issue-33262.rs new file mode 100644 index 000000000..3a612f95c --- /dev/null +++ b/src/test/ui/parser/issues/issue-33262.rs @@ -0,0 +1,6 @@ +// Issue #33262 + +pub fn main() { + for i in 0..a as { } + //~^ ERROR expected type, found `{` +} diff --git a/src/test/ui/parser/issues/issue-33262.stderr b/src/test/ui/parser/issues/issue-33262.stderr new file mode 100644 index 000000000..2aff32839 --- /dev/null +++ b/src/test/ui/parser/issues/issue-33262.stderr @@ -0,0 +1,8 @@ +error: expected type, found `{` + --> $DIR/issue-33262.rs:4:22 + | +LL | for i in 0..a as { } + | ^ expected type + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-33413.rs b/src/test/ui/parser/issues/issue-33413.rs new file mode 100644 index 000000000..7291732ce --- /dev/null +++ b/src/test/ui/parser/issues/issue-33413.rs @@ -0,0 +1,9 @@ +struct S; + +impl S { + fn f(*, a: u8) -> u8 {} + //~^ ERROR expected parameter name, found `*` + //~| ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-33413.stderr b/src/test/ui/parser/issues/issue-33413.stderr new file mode 100644 index 000000000..b7250f3b0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-33413.stderr @@ -0,0 +1,22 @@ +error: expected parameter name, found `*` + --> $DIR/issue-33413.rs:4:10 + | +LL | fn f(*, a: u8) -> u8 {} + | ^ expected parameter name + +error[E0308]: mismatched types + --> $DIR/issue-33413.rs:4:23 + | +LL | fn f(*, a: u8) -> u8 {} + | - ^^ expected `u8`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | +help: consider returning the local binding `a` + | +LL | fn f(*, a: u8) -> u8 { a } + | + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-33418.fixed b/src/test/ui/parser/issues/issue-33418.fixed new file mode 100644 index 000000000..ed885ae14 --- /dev/null +++ b/src/test/ui/parser/issues/issue-33418.fixed @@ -0,0 +1,19 @@ +// run-rustfix + +trait Tr {} +//~^ ERROR negative bounds are not supported +trait Tr2: SuperA {} +//~^ ERROR negative bounds are not supported +trait Tr3: SuperB {} +//~^ ERROR negative bounds are not supported +trait Tr4: SuperB + SuperD {} +//~^ ERROR negative bounds are not supported +trait Tr5 {} +//~^ ERROR negative bounds are not supported + +trait SuperA {} +trait SuperB {} +trait SuperC {} +trait SuperD {} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-33418.rs b/src/test/ui/parser/issues/issue-33418.rs new file mode 100644 index 000000000..9934284ab --- /dev/null +++ b/src/test/ui/parser/issues/issue-33418.rs @@ -0,0 +1,21 @@ +// run-rustfix + +trait Tr: !SuperA {} +//~^ ERROR negative bounds are not supported +trait Tr2: SuperA + !SuperB {} +//~^ ERROR negative bounds are not supported +trait Tr3: !SuperA + SuperB {} +//~^ ERROR negative bounds are not supported +trait Tr4: !SuperA + SuperB + + !SuperC + SuperD {} +//~^ ERROR negative bounds are not supported +trait Tr5: !SuperA + + !SuperB {} +//~^ ERROR negative bounds are not supported + +trait SuperA {} +trait SuperB {} +trait SuperC {} +trait SuperD {} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-33418.stderr b/src/test/ui/parser/issues/issue-33418.stderr new file mode 100644 index 000000000..9a8733e89 --- /dev/null +++ b/src/test/ui/parser/issues/issue-33418.stderr @@ -0,0 +1,36 @@ +error: negative bounds are not supported + --> $DIR/issue-33418.rs:3:9 + | +LL | trait Tr: !SuperA {} + | ^^^^^^^^^ negative bounds are not supported + +error: negative bounds are not supported + --> $DIR/issue-33418.rs:5:19 + | +LL | trait Tr2: SuperA + !SuperB {} + | ^^^^^^^^^ negative bounds are not supported + +error: negative bounds are not supported + --> $DIR/issue-33418.rs:7:10 + | +LL | trait Tr3: !SuperA + SuperB {} + | ^^^^^^^^^ negative bounds are not supported + +error: negative bounds are not supported + --> $DIR/issue-33418.rs:9:10 + | +LL | trait Tr4: !SuperA + SuperB + | ^^^^^^^^^ +LL | + !SuperC + SuperD {} + | ^^^^^^^^^ negative bounds are not supported + +error: negative bounds are not supported + --> $DIR/issue-33418.rs:12:10 + | +LL | trait Tr5: !SuperA + | ^^^^^^^^^ +LL | + !SuperB {} + | ^^^^^^^^^ negative bounds are not supported + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/parser/issues/issue-33455.rs b/src/test/ui/parser/issues/issue-33455.rs new file mode 100644 index 000000000..6dff63f5c --- /dev/null +++ b/src/test/ui/parser/issues/issue-33455.rs @@ -0,0 +1 @@ +use foo.bar; //~ ERROR expected one of `::`, `;`, or `as`, found `.` diff --git a/src/test/ui/parser/issues/issue-33455.stderr b/src/test/ui/parser/issues/issue-33455.stderr new file mode 100644 index 000000000..c535ef23b --- /dev/null +++ b/src/test/ui/parser/issues/issue-33455.stderr @@ -0,0 +1,8 @@ +error: expected one of `::`, `;`, or `as`, found `.` + --> $DIR/issue-33455.rs:1:8 + | +LL | use foo.bar; + | ^ expected one of `::`, `;`, or `as` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-34222-1.rs b/src/test/ui/parser/issues/issue-34222-1.rs new file mode 100644 index 000000000..d36dddc97 --- /dev/null +++ b/src/test/ui/parser/issues/issue-34222-1.rs @@ -0,0 +1,3 @@ +fn main() { + /// comment //~ ERROR found a documentation comment that doesn't document anything +} diff --git a/src/test/ui/parser/issues/issue-34222-1.stderr b/src/test/ui/parser/issues/issue-34222-1.stderr new file mode 100644 index 000000000..0799656b0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-34222-1.stderr @@ -0,0 +1,11 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/issue-34222-1.rs:2:5 + | +LL | /// comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/issues/issue-34255-1.rs b/src/test/ui/parser/issues/issue-34255-1.rs new file mode 100644 index 000000000..c70cd8b50 --- /dev/null +++ b/src/test/ui/parser/issues/issue-34255-1.rs @@ -0,0 +1,10 @@ +enum Test { + Drill { + field: i32, + } +} + +fn main() { + Test::Drill(field: 42); + //~^ ERROR invalid `struct` delimiters or `fn` call arguments +} diff --git a/src/test/ui/parser/issues/issue-34255-1.stderr b/src/test/ui/parser/issues/issue-34255-1.stderr new file mode 100644 index 000000000..0e2b0d62e --- /dev/null +++ b/src/test/ui/parser/issues/issue-34255-1.stderr @@ -0,0 +1,18 @@ +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/issue-34255-1.rs:8:5 + | +LL | Test::Drill(field: 42); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: if `Test::Drill` is a struct, use braces as delimiters + | +LL | Test::Drill { field: 42 }; + | ~ ~ +help: if `Test::Drill` is a function, use the arguments directly + | +LL - Test::Drill(field: 42); +LL + Test::Drill(42); + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs new file mode 100644 index 000000000..7bd4b3a16 --- /dev/null +++ b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs @@ -0,0 +1,171 @@ +// edition:2018 +#![crate_type = "lib"] +#![feature(type_ascription)] +use std::future::Future; +use std::pin::Pin; + +// This tests the parser for "x as Y[z]". It errors, but we want to give useful +// errors and parse such that further code gives useful errors. +pub fn index_after_as_cast() { + vec![1, 2, 3] as Vec<i32>[0]; + //~^ ERROR: cast cannot be followed by indexing + vec![1, 2, 3]: Vec<i32>[0]; + //~^ ERROR: type ascription cannot be followed by indexing +} + +pub fn index_after_cast_to_index() { + (&[0]) as &[i32][0]; + //~^ ERROR: cast cannot be followed by indexing + (&[0i32]): &[i32; 1][0]; + //~^ ERROR: type ascription cannot be followed by indexing +} + +pub fn cast_after_cast() { + if 5u64 as i32 as u16 == 0u16 { + + } + if 5u64: u64: u64 == 0u64 { + + } + let _ = 5u64: u64: u64 as u8 as i8 == 9i8; + let _ = 0i32: i32: i32; + let _ = 0 as i32: i32; + let _ = 0i32: i32 as i32; + let _ = 0 as i32 as i32; + let _ = 0i32: i32: i32 as u32 as i32; +} + +pub fn cast_cast_method_call() { + let _ = 0i32: i32: i32.count_ones(); + //~^ ERROR: type ascription cannot be followed by a method call + let _ = 0 as i32: i32.count_ones(); + //~^ ERROR: type ascription cannot be followed by a method call + let _ = 0i32: i32 as i32.count_ones(); + //~^ ERROR: cast cannot be followed by a method call + let _ = 0 as i32 as i32.count_ones(); + //~^ ERROR: cast cannot be followed by a method call + let _ = 0i32: i32: i32 as u32 as i32.count_ones(); + //~^ ERROR: cast cannot be followed by a method call + let _ = 0i32: i32.count_ones(): u32; + //~^ ERROR: type ascription cannot be followed by a method call + let _ = 0 as i32.count_ones(): u32; + //~^ ERROR: cast cannot be followed by a method call + let _ = 0i32: i32.count_ones() as u32; + //~^ ERROR: type ascription cannot be followed by a method call + let _ = 0 as i32.count_ones() as u32; + //~^ ERROR: cast cannot be followed by a method call + let _ = 0i32: i32: i32.count_ones() as u32 as i32; + //~^ ERROR: type ascription cannot be followed by a method call +} + +pub fn multiline_error() { + let _ = 0 + as i32 + .count_ones(); + //~^^^ ERROR: cast cannot be followed by a method call +} + +// this tests that the precedence for `!x as Y.Z` is still what we expect +pub fn precedence() { + let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0]; + //~^ ERROR: cast cannot be followed by indexing +} + +pub fn method_calls() { + 0 as i32.max(0); + //~^ ERROR: cast cannot be followed by a method call + 0: i32.max(0); + //~^ ERROR: type ascription cannot be followed by a method call +} + +pub fn complex() { + let _ = format!( + "{} and {}", + if true { 33 } else { 44 } as i32.max(0), + //~^ ERROR: cast cannot be followed by a method call + if true { 33 } else { 44 }: i32.max(0) + //~^ ERROR: type ascription cannot be followed by a method call + ); +} + +pub fn in_condition() { + if 5u64 as i32.max(0) == 0 { + //~^ ERROR: cast cannot be followed by a method call + } + if 5u64: u64.max(0) == 0 { + //~^ ERROR: type ascription cannot be followed by a method call + } +} + +pub fn inside_block() { + let _ = if true { + 5u64 as u32.max(0) == 0 + //~^ ERROR: cast cannot be followed by a method call + } else { false }; + let _ = if true { + 5u64: u64.max(0) == 0 + //~^ ERROR: type ascription cannot be followed by a method call + } else { false }; +} + +static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); +//~^ ERROR: cast cannot be followed by indexing + +static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); +//~^ ERROR: type ascription cannot be followed by indexing + + +pub fn cast_then_try() -> Result<u64,u64> { + Err(0u64) as Result<u64,u64>?; + //~^ ERROR: cast cannot be followed by `?` + Err(0u64): Result<u64,u64>?; + //~^ ERROR: type ascription cannot be followed by `?` + Ok(1) +} + + +pub fn cast_then_call() { + type F = fn(u8); + // type ascription won't actually do [unique drop fn type] -> fn(u8) casts. + let drop_ptr = drop as fn(u8); + drop as F(); + //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] + drop_ptr: F(); + //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] +} + +pub fn cast_to_fn_should_work() { + let drop_ptr = drop as fn(u8); + drop as fn(u8); + drop_ptr: fn(u8); +} + +pub fn parens_after_cast_error() { + let drop_ptr = drop as fn(u8); + drop as fn(u8)(0); + //~^ ERROR: cast cannot be followed by a function call + drop_ptr: fn(u8)(0); + //~^ ERROR: type ascription cannot be followed by a function call +} + +pub async fn cast_then_await() { + Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await; + //~^ ERROR: cast cannot be followed by `.await` + + Box::pin(noop()): Pin<Box<_>>.await; + //~^ ERROR: type ascription cannot be followed by `.await` +} + +pub async fn noop() {} + +#[derive(Default)] +pub struct Foo { + pub bar: u32, +} + +pub fn struct_field() { + Foo::default() as Foo.bar; + //~^ ERROR: cannot be followed by a field access + Foo::default(): Foo.bar; + //~^ ERROR: type ascription cannot be followed by a field access +} diff --git a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr new file mode 100644 index 000000000..0c328bde2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -0,0 +1,472 @@ +error: cast cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:10:5 + | +LL | vec![1, 2, 3] as Vec<i32>[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (vec![1, 2, 3] as Vec<i32>)[0]; + | + + + +error: type ascription cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:12:5 + | +LL | vec![1, 2, 3]: Vec<i32>[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (vec![1, 2, 3]: Vec<i32>)[0]; + | + + +help: alternatively, remove the type ascription + | +LL - vec![1, 2, 3]: Vec<i32>[0]; +LL + vec![1, 2, 3][0]; + | + +error: cast cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:17:5 + | +LL | (&[0]) as &[i32][0]; + | ^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | ((&[0]) as &[i32])[0]; + | + + + +error: type ascription cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:19:5 + | +LL | (&[0i32]): &[i32; 1][0]; + | ^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | ((&[0i32]): &[i32; 1])[0]; + | + + +help: alternatively, remove the type ascription + | +LL - (&[0i32]): &[i32; 1][0]; +LL + (&[0i32])[0]; + | + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:39:13 + | +LL | let _ = 0i32: i32: i32.count_ones(); + | ^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32: i32).count_ones(); + | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32: i32.count_ones(); +LL + let _ = 0i32: i32.count_ones(); + | + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:41:13 + | +LL | let _ = 0 as i32: i32.count_ones(); + | ^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32: i32).count_ones(); + | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0 as i32: i32.count_ones(); +LL + let _ = 0 as i32.count_ones(); + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:43:13 + | +LL | let _ = 0i32: i32 as i32.count_ones(); + | ^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32 as i32).count_ones(); + | + + + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:45:13 + | +LL | let _ = 0 as i32 as i32.count_ones(); + | ^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32 as i32).count_ones(); + | + + + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:47:13 + | +LL | let _ = 0i32: i32: i32 as u32 as i32.count_ones(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32: i32 as u32 as i32).count_ones(); + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:49:13 + | +LL | let _ = 0i32: i32.count_ones(): u32; + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32).count_ones(): u32; + | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32.count_ones(): u32; +LL + let _ = 0i32.count_ones(): u32; + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:51:13 + | +LL | let _ = 0 as i32.count_ones(): u32; + | ^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32).count_ones(): u32; + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:53:13 + | +LL | let _ = 0i32: i32.count_ones() as u32; + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32).count_ones() as u32; + | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32.count_ones() as u32; +LL + let _ = 0i32.count_ones() as u32; + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:55:13 + | +LL | let _ = 0 as i32.count_ones() as u32; + | ^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32).count_ones() as u32; + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:57:13 + | +LL | let _ = 0i32: i32: i32.count_ones() as u32 as i32; + | ^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32; + | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32; +LL + let _ = 0i32: i32.count_ones() as u32 as i32; + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:62:13 + | +LL | let _ = 0 + | _____________^ +LL | | as i32 + | |______________^ + | +help: try surrounding the expression in parentheses + | +LL ~ let _ = (0 +LL ~ as i32) + | + +error: cast cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:70:18 + | +LL | let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let x: i32 = (&vec![1, 2, 3] as &Vec<i32>)[0]; + | + + + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:75:5 + | +LL | 0 as i32.max(0); + | ^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (0 as i32).max(0); + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:77:5 + | +LL | 0: i32.max(0); + | ^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (0: i32).max(0); + | + + +help: alternatively, remove the type ascription + | +LL - 0: i32.max(0); +LL + 0.max(0); + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:92:8 + | +LL | if 5u64 as i32.max(0) == 0 { + | ^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | if (5u64 as i32).max(0) == 0 { + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:95:8 + | +LL | if 5u64: u64.max(0) == 0 { + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | if (5u64: u64).max(0) == 0 { + | + + +help: alternatively, remove the type ascription + | +LL - if 5u64: u64.max(0) == 0 { +LL + if 5u64.max(0) == 0 { + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:102:9 + | +LL | 5u64 as u32.max(0) == 0 + | ^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (5u64 as u32).max(0) == 0 + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:106:9 + | +LL | 5u64: u64.max(0) == 0 + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (5u64: u64).max(0) == 0 + | + + +help: alternatively, remove the type ascription + | +LL - 5u64: u64.max(0) == 0 +LL + 5u64.max(0) == 0 + | + +error: cast cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:111:24 + | +LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); + | ^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]); + | + + + +error: type ascription cannot be followed by indexing + --> $DIR/issue-35813-postfix-after-cast.rs:114:25 + | +LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]); + | + + +help: alternatively, remove the type ascription + | +LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); +LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]); + | + +error: cast cannot be followed by `?` + --> $DIR/issue-35813-postfix-after-cast.rs:119:5 + | +LL | Err(0u64) as Result<u64,u64>?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Err(0u64) as Result<u64,u64>)?; + | + + + +error: type ascription cannot be followed by `?` + --> $DIR/issue-35813-postfix-after-cast.rs:121:5 + | +LL | Err(0u64): Result<u64,u64>?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Err(0u64): Result<u64,u64>)?; + | + + +help: alternatively, remove the type ascription + | +LL - Err(0u64): Result<u64,u64>?; +LL + Err(0u64)?; + | + +error: cast cannot be followed by a function call + --> $DIR/issue-35813-postfix-after-cast.rs:145:5 + | +LL | drop as fn(u8)(0); + | ^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (drop as fn(u8))(0); + | + + + +error: type ascription cannot be followed by a function call + --> $DIR/issue-35813-postfix-after-cast.rs:147:5 + | +LL | drop_ptr: fn(u8)(0); + | ^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (drop_ptr: fn(u8))(0); + | + + +help: alternatively, remove the type ascription + | +LL - drop_ptr: fn(u8)(0); +LL + drop_ptr(0); + | + +error: cast cannot be followed by `.await` + --> $DIR/issue-35813-postfix-after-cast.rs:152:5 + | +LL | Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>).await; + | + + + +error: type ascription cannot be followed by `.await` + --> $DIR/issue-35813-postfix-after-cast.rs:155:5 + | +LL | Box::pin(noop()): Pin<Box<_>>.await; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Box::pin(noop()): Pin<Box<_>>).await; + | + + +help: alternatively, remove the type ascription + | +LL - Box::pin(noop()): Pin<Box<_>>.await; +LL + Box::pin(noop()).await; + | + +error: cast cannot be followed by a field access + --> $DIR/issue-35813-postfix-after-cast.rs:167:5 + | +LL | Foo::default() as Foo.bar; + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Foo::default() as Foo).bar; + | + + + +error: type ascription cannot be followed by a field access + --> $DIR/issue-35813-postfix-after-cast.rs:169:5 + | +LL | Foo::default(): Foo.bar; + | ^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Foo::default(): Foo).bar; + | + + +help: alternatively, remove the type ascription + | +LL - Foo::default(): Foo.bar; +LL + Foo::default().bar; + | + +error: cast cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:84:9 + | +LL | if true { 33 } else { 44 } as i32.max(0), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (if true { 33 } else { 44 } as i32).max(0), + | + + + +error: type ascription cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:86:9 + | +LL | if true { 33 } else { 44 }: i32.max(0) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (if true { 33 } else { 44 }: i32).max(0) + | + + +help: alternatively, remove the type ascription + | +LL - if true { 33 } else { 44 }: i32.max(0) +LL + if true { 33 } else { 44 }.max(0) + | + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-35813-postfix-after-cast.rs:131:13 + | +LL | drop as F(); + | ^^^ only `Fn` traits may use parentheses + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-35813-postfix-after-cast.rs:133:15 + | +LL | drop_ptr: F(); + | ^^^ only `Fn` traits may use parentheses + +error: aborting due to 36 previous errors + +For more information about this error, try `rustc --explain E0214`. diff --git a/src/test/ui/parser/issues/issue-41155.rs b/src/test/ui/parser/issues/issue-41155.rs new file mode 100644 index 000000000..5a7488e6f --- /dev/null +++ b/src/test/ui/parser/issues/issue-41155.rs @@ -0,0 +1,7 @@ +struct S; + +impl S { + pub //~ ERROR visibility `pub` is not followed by an item +} //~ ERROR non-item in item list + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-41155.stderr b/src/test/ui/parser/issues/issue-41155.stderr new file mode 100644 index 000000000..8491afae2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-41155.stderr @@ -0,0 +1,22 @@ +error: visibility `pub` is not followed by an item + --> $DIR/issue-41155.rs:4:5 + | +LL | pub + | ^^^ the visibility + | + = help: you likely meant to define an item, e.g., `pub fn foo() {}` + +error: non-item in item list + --> $DIR/issue-41155.rs:5:1 + | +LL | impl S { + | - item list starts here +LL | pub +LL | } + | ^ + | | + | non-item starts here + | item list ends here + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-43196.rs b/src/test/ui/parser/issues/issue-43196.rs new file mode 100644 index 000000000..0eefa01ce --- /dev/null +++ b/src/test/ui/parser/issues/issue-43196.rs @@ -0,0 +1,6 @@ +fn main() { + | +} +//~^ ERROR expected `|`, found `}` +| +//~^ ERROR expected item, found `|` diff --git a/src/test/ui/parser/issues/issue-43196.stderr b/src/test/ui/parser/issues/issue-43196.stderr new file mode 100644 index 000000000..4f7ed5cc6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-43196.stderr @@ -0,0 +1,16 @@ +error: expected `|`, found `}` + --> $DIR/issue-43196.rs:3:1 + | +LL | | + | - expected `|` +LL | } + | ^ unexpected token + +error: expected item, found `|` + --> $DIR/issue-43196.rs:5:1 + | +LL | | + | ^ expected item + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-43692.rs b/src/test/ui/parser/issues/issue-43692.rs new file mode 100644 index 000000000..baf8bafb8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-43692.rs @@ -0,0 +1,3 @@ +fn main() { + '\u{_10FFFF}'; //~ ERROR invalid start of unicode escape +} diff --git a/src/test/ui/parser/issues/issue-43692.stderr b/src/test/ui/parser/issues/issue-43692.stderr new file mode 100644 index 000000000..baf998035 --- /dev/null +++ b/src/test/ui/parser/issues/issue-43692.stderr @@ -0,0 +1,8 @@ +error: invalid start of unicode escape: `_` + --> $DIR/issue-43692.rs:2:9 + | +LL | '\u{_10FFFF}'; + | ^ invalid start of unicode escape + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-44021.rs b/src/test/ui/parser/issues/issue-44021.rs new file mode 100644 index 000000000..0b9558cc9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-44021.rs @@ -0,0 +1,6 @@ +struct MyStruct; +impl MyStruct { + fn f() {|x, y} //~ ERROR expected one of `:`, `@`, or `|`, found `}` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-44021.stderr b/src/test/ui/parser/issues/issue-44021.stderr new file mode 100644 index 000000000..b888cd989 --- /dev/null +++ b/src/test/ui/parser/issues/issue-44021.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `@`, or `|`, found `}` + --> $DIR/issue-44021.rs:3:18 + | +LL | fn f() {|x, y} + | ^ expected one of `:`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-44406.rs b/src/test/ui/parser/issues/issue-44406.rs new file mode 100644 index 000000000..a5b7e83a0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-44406.rs @@ -0,0 +1,10 @@ +macro_rules! foo { + ($rest: tt) => { + bar(baz: $rest) //~ ERROR invalid `struct` delimiters or `fn` call arguments + } +} + +fn main() { + foo!(true); + //~^ ERROR expected identifier, found keyword +} diff --git a/src/test/ui/parser/issues/issue-44406.stderr b/src/test/ui/parser/issues/issue-44406.stderr new file mode 100644 index 000000000..1f0c1ea4c --- /dev/null +++ b/src/test/ui/parser/issues/issue-44406.stderr @@ -0,0 +1,33 @@ +error: expected identifier, found keyword `true` + --> $DIR/issue-44406.rs:8:10 + | +LL | foo!(true); + | ^^^^ expected identifier, found keyword + | +help: escape `true` to use it as an identifier + | +LL | foo!(r#true); + | ++ + +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/issue-44406.rs:3:9 + | +LL | bar(baz: $rest) + | ^^^^^^^^^^^^^^^ +... +LL | foo!(true); + | ---------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: if `bar` is a struct, use braces as delimiters + | +LL | bar { } + | ~ +help: if `bar` is a function, use the arguments directly + | +LL - bar(baz: $rest) +LL + bar(: $rest) + | + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-45296.rs b/src/test/ui/parser/issues/issue-45296.rs new file mode 100644 index 000000000..d3a97e89f --- /dev/null +++ b/src/test/ui/parser/issues/issue-45296.rs @@ -0,0 +1,6 @@ +fn main() { + let unused = (); + + #![allow(unused_variables)] //~ ERROR not permitted in this context + fn foo() {} +} diff --git a/src/test/ui/parser/issues/issue-45296.stderr b/src/test/ui/parser/issues/issue-45296.stderr new file mode 100644 index 000000000..081a72054 --- /dev/null +++ b/src/test/ui/parser/issues/issue-45296.stderr @@ -0,0 +1,17 @@ +error: an inner attribute is not permitted in this context + --> $DIR/issue-45296.rs:4:5 + | +LL | #![allow(unused_variables)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![allow(unused_variables)] +LL + #[allow(unused_variables)] + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-46186.fixed b/src/test/ui/parser/issues/issue-46186.fixed new file mode 100644 index 000000000..2cb5a4996 --- /dev/null +++ b/src/test/ui/parser/issues/issue-46186.fixed @@ -0,0 +1,8 @@ +// run-rustfix + +pub struct Struct { + pub a: usize, +} +//~^ ERROR expected item, found `;` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-46186.rs b/src/test/ui/parser/issues/issue-46186.rs new file mode 100644 index 000000000..84cad38c5 --- /dev/null +++ b/src/test/ui/parser/issues/issue-46186.rs @@ -0,0 +1,8 @@ +// run-rustfix + +pub struct Struct { + pub a: usize, +}; +//~^ ERROR expected item, found `;` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-46186.stderr b/src/test/ui/parser/issues/issue-46186.stderr new file mode 100644 index 000000000..0766c8a33 --- /dev/null +++ b/src/test/ui/parser/issues/issue-46186.stderr @@ -0,0 +1,10 @@ +error: expected item, found `;` + --> $DIR/issue-46186.rs:5:2 + | +LL | }; + | ^ help: remove this semicolon + | + = help: braced struct declarations are not followed by a semicolon + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs new file mode 100644 index 000000000..48a679b2d --- /dev/null +++ b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs @@ -0,0 +1,44 @@ +fn main() {} + +macro_rules! expand_to_enum { + () => { + enum BadE {} + //~^ ERROR enum is not supported in `trait`s or `impl`s + //~| ERROR enum is not supported in `trait`s or `impl`s + //~| ERROR enum is not supported in `extern` blocks + }; +} + +macro_rules! mac_impl { + ($($i:item)*) => { + struct S; + impl S { $($i)* } + } +} + +mac_impl! { + struct BadS; //~ ERROR struct is not supported in `trait`s or `impl`s + expand_to_enum!(); +} + +macro_rules! mac_trait { + ($($i:item)*) => { + trait T { $($i)* } + } +} + +mac_trait! { + struct BadS; //~ ERROR struct is not supported in `trait`s or `impl`s + expand_to_enum!(); +} + +macro_rules! mac_extern { + ($($i:item)*) => { + extern "C" { $($i)* } + } +} + +mac_extern! { + struct BadS; //~ ERROR struct is not supported in `extern` blocks + expand_to_enum!(); +} diff --git a/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr new file mode 100644 index 000000000..fdef8ff6d --- /dev/null +++ b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr @@ -0,0 +1,62 @@ +error: struct is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:20:5 + | +LL | struct BadS; + | ^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 + | +LL | enum BadE {} + | ^^^^^^^^^ +... +LL | expand_to_enum!(); + | ----------------- in this macro invocation + | + = help: consider moving the enum out to a nearby module scope + = note: this error originates in the macro `expand_to_enum` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:31:5 + | +LL | struct BadS; + | ^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 + | +LL | enum BadE {} + | ^^^^^^^^^ +... +LL | expand_to_enum!(); + | ----------------- in this macro invocation + | + = help: consider moving the enum out to a nearby module scope + = note: this error originates in the macro `expand_to_enum` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: struct is not supported in `extern` blocks + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:42:5 + | +LL | struct BadS; + | ^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: enum is not supported in `extern` blocks + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 + | +LL | enum BadE {} + | ^^^^^^^^^ +... +LL | expand_to_enum!(); + | ----------------- in this macro invocation + | + = help: consider moving the enum out to a nearby module scope + = note: this error originates in the macro `expand_to_enum` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs new file mode 100644 index 000000000..8592f8a72 --- /dev/null +++ b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs @@ -0,0 +1,34 @@ +// check-pass + +fn main() {} + +macro_rules! mac_impl { + ($i:item) => { + struct S; + impl S { $i } + } +} + +mac_impl! { + fn foo() {} +} + +macro_rules! mac_trait { + ($i:item) => { + trait T { $i } + } +} + +mac_trait! { + fn foo() {} +} + +macro_rules! mac_extern { + ($i:item) => { + extern "C" { $i } + } +} + +mac_extern! { + fn foo(); +} diff --git a/src/test/ui/parser/issues/issue-48508-aux.rs b/src/test/ui/parser/issues/issue-48508-aux.rs new file mode 100644 index 000000000..ebdc70a04 --- /dev/null +++ b/src/test/ui/parser/issues/issue-48508-aux.rs @@ -0,0 +1,7 @@ +// run-pass +// ignore-test Not a test. Used by issue-48508.rs + +pub fn other() -> f64 { + let µ = 1.0; + µ +} diff --git a/src/test/ui/parser/issues/issue-48508.rs b/src/test/ui/parser/issues/issue-48508.rs new file mode 100644 index 000000000..37d04c5d6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-48508.rs @@ -0,0 +1,20 @@ +// run-pass +// Regression test for issue #48508: +// +// Confusion between global and local file offsets caused incorrect handling of multibyte character +// spans when compiling multiple files. One visible effect was an ICE generating debug information +// when a multibyte character is at the end of a scope. The problematic code is actually in +// issue-48508-aux.rs + +// compile-flags:-g +// ignore-pretty issue #37195 +// ignore-asmjs wasm2js does not support source maps yet + +#![allow(uncommon_codepoints)] + +#[path = "issue-48508-aux.rs"] +mod other_file; + +fn main() { + other_file::other(); +} diff --git a/src/test/ui/parser/issues/issue-48636.fixed b/src/test/ui/parser/issues/issue-48636.fixed new file mode 100644 index 000000000..87c19a32d --- /dev/null +++ b/src/test/ui/parser/issues/issue-48636.fixed @@ -0,0 +1,12 @@ +// run-rustfix + +#![allow(dead_code)] + +struct S { + x: u8, + /// The ID of the parent core + y: u8, +} +//~^^^ ERROR found a documentation comment that doesn't document anything + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-48636.rs b/src/test/ui/parser/issues/issue-48636.rs new file mode 100644 index 000000000..8610dc2f7 --- /dev/null +++ b/src/test/ui/parser/issues/issue-48636.rs @@ -0,0 +1,12 @@ +// run-rustfix + +#![allow(dead_code)] + +struct S { + x: u8 + /// The ID of the parent core + y: u8, +} +//~^^^ ERROR found a documentation comment that doesn't document anything + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-48636.stderr b/src/test/ui/parser/issues/issue-48636.stderr new file mode 100644 index 000000000..462723d1d --- /dev/null +++ b/src/test/ui/parser/issues/issue-48636.stderr @@ -0,0 +1,13 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/issue-48636.rs:7:5 + | +LL | x: u8 + | - help: missing comma here: `,` +LL | /// The ID of the parent core + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: doc comments must come before what they document, maybe a comment was intended with `//`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/parser/issues/issue-49040.rs b/src/test/ui/parser/issues/issue-49040.rs new file mode 100644 index 000000000..b7a541dd6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-49040.rs @@ -0,0 +1,3 @@ +#![allow(unused_variables)]; //~ ERROR expected item, found `;` +//~^ ERROR `main` function +fn foo() {} diff --git a/src/test/ui/parser/issues/issue-49040.stderr b/src/test/ui/parser/issues/issue-49040.stderr new file mode 100644 index 000000000..8af7838c7 --- /dev/null +++ b/src/test/ui/parser/issues/issue-49040.stderr @@ -0,0 +1,15 @@ +error: expected item, found `;` + --> $DIR/issue-49040.rs:1:28 + | +LL | #![allow(unused_variables)]; + | ^ help: remove this semicolon + +error[E0601]: `main` function not found in crate `issue_49040` + --> $DIR/issue-49040.rs:1:29 + | +LL | #![allow(unused_variables)]; + | ^ consider adding a `main` function to `$DIR/issue-49040.rs` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/parser/issues/issue-51602.rs b/src/test/ui/parser/issues/issue-51602.rs new file mode 100644 index 000000000..0e96ca914 --- /dev/null +++ b/src/test/ui/parser/issues/issue-51602.rs @@ -0,0 +1,6 @@ +fn main(){ + if i in 1..10 { +//~^ ERROR expected `{`, found keyword `in` + break; + } +} diff --git a/src/test/ui/parser/issues/issue-51602.stderr b/src/test/ui/parser/issues/issue-51602.stderr new file mode 100644 index 000000000..4a5653fdb --- /dev/null +++ b/src/test/ui/parser/issues/issue-51602.stderr @@ -0,0 +1,14 @@ +error: expected `{`, found keyword `in` + --> $DIR/issue-51602.rs:2:10 + | +LL | if i in 1..10 { + | ^^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-51602.rs:2:8 + | +LL | if i in 1..10 { + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-52496.rs b/src/test/ui/parser/issues/issue-52496.rs new file mode 100644 index 000000000..05461f8b8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-52496.rs @@ -0,0 +1,12 @@ +struct Foo { bar: f64, baz: i64, bat: i64 } + +fn main() { + let _ = Foo { bar: .5, baz: 42 }; + //~^ ERROR float literals must have an integer part + //~| ERROR missing field `bat` in initializer of `Foo` + let bar = 1.5f32; + let _ = Foo { bar.into(), bat: -1, . }; + //~^ ERROR expected one of + //~| ERROR missing fields `bar` and `baz` in initializer of `Foo` + //~| ERROR expected identifier, found `.` +} diff --git a/src/test/ui/parser/issues/issue-52496.stderr b/src/test/ui/parser/issues/issue-52496.stderr new file mode 100644 index 000000000..77335c64c --- /dev/null +++ b/src/test/ui/parser/issues/issue-52496.stderr @@ -0,0 +1,38 @@ +error: float literals must have an integer part + --> $DIR/issue-52496.rs:4:24 + | +LL | let _ = Foo { bar: .5, baz: 42 }; + | ^^ help: must have an integer part: `0.5` + +error: expected one of `,`, `:`, or `}`, found `.` + --> $DIR/issue-52496.rs:8:22 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | --- - ^ expected one of `,`, `:`, or `}` + | | | + | | help: try naming a field: `bar:` + | while parsing this struct + +error: expected identifier, found `.` + --> $DIR/issue-52496.rs:8:40 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | --- ^ expected identifier + | | + | while parsing this struct + +error[E0063]: missing field `bat` in initializer of `Foo` + --> $DIR/issue-52496.rs:4:13 + | +LL | let _ = Foo { bar: .5, baz: 42 }; + | ^^^ missing `bat` + +error[E0063]: missing fields `bar` and `baz` in initializer of `Foo` + --> $DIR/issue-52496.rs:8:13 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | ^^^ missing `bar` and `baz` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0063`. diff --git a/src/test/ui/parser/issues/issue-54521-1.rs b/src/test/ui/parser/issues/issue-54521-1.rs new file mode 100644 index 000000000..8a682ef0a --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-1.rs @@ -0,0 +1,16 @@ +// check-pass + +// This test checks that the `remove extra angle brackets` error doesn't happen for some +// potential edge-cases.. + +struct X { + len: u32, +} + +fn main() { + let x = X { len: 3 }; + + let _ = x.len > (3); + + let _ = x.len >> (3); +} diff --git a/src/test/ui/parser/issues/issue-54521-2.fixed b/src/test/ui/parser/issues/issue-54521-2.fixed new file mode 100644 index 000000000..a91c4fe43 --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-2.fixed @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = Vec::<usize>>>::new(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = Vec::<usize>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::<usize>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::<usize>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::<usize>::new(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/parser/issues/issue-54521-2.rs b/src/test/ui/parser/issues/issue-54521-2.rs new file mode 100644 index 000000000..3639aac87 --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-2.rs @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = Vec::<usize>>>::new(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = Vec::<usize>>>>>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::<usize>>>>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::<usize>>>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::<usize>>::new(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/parser/issues/issue-54521-2.stderr b/src/test/ui/parser/issues/issue-54521-2.stderr new file mode 100644 index 000000000..9556b83b7 --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-2.stderr @@ -0,0 +1,26 @@ +error: unmatched angle brackets + --> $DIR/issue-54521-2.rs:11:25 + | +LL | let _ = Vec::<usize>>>>>::new(); + | ^^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-54521-2.rs:14:25 + | +LL | let _ = Vec::<usize>>>>::new(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-54521-2.rs:17:25 + | +LL | let _ = Vec::<usize>>>::new(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-54521-2.rs:20:25 + | +LL | let _ = Vec::<usize>>::new(); + | ^ help: remove extra angle bracket + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/issues/issue-54521-3.fixed b/src/test/ui/parser/issues/issue-54521-3.fixed new file mode 100644 index 000000000..84ab6866c --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-3.fixed @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/parser/issues/issue-54521-3.rs b/src/test/ui/parser/issues/issue-54521-3.rs new file mode 100644 index 000000000..f1d685041 --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-3.rs @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/parser/issues/issue-54521-3.stderr b/src/test/ui/parser/issues/issue-54521-3.stderr new file mode 100644 index 000000000..0f23dd621 --- /dev/null +++ b/src/test/ui/parser/issues/issue-54521-3.stderr @@ -0,0 +1,26 @@ +error: unmatched angle brackets + --> $DIR/issue-54521-3.rs:11:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>>(); + | ^^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-54521-3.rs:14:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-54521-3.rs:17:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-54521-3.rs:20:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>(); + | ^ help: remove extra angle bracket + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/issues/issue-5544-a.rs b/src/test/ui/parser/issues/issue-5544-a.rs new file mode 100644 index 000000000..3c239c73b --- /dev/null +++ b/src/test/ui/parser/issues/issue-5544-a.rs @@ -0,0 +1,4 @@ +fn main() { + let __isize = 340282366920938463463374607431768211456; // 2^128 + //~^ ERROR integer literal is too large +} diff --git a/src/test/ui/parser/issues/issue-5544-a.stderr b/src/test/ui/parser/issues/issue-5544-a.stderr new file mode 100644 index 000000000..de579c3c1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-5544-a.stderr @@ -0,0 +1,8 @@ +error: integer literal is too large + --> $DIR/issue-5544-a.rs:2:19 + | +LL | let __isize = 340282366920938463463374607431768211456; // 2^128 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-5544-b.rs b/src/test/ui/parser/issues/issue-5544-b.rs new file mode 100644 index 000000000..93f2ff271 --- /dev/null +++ b/src/test/ui/parser/issues/issue-5544-b.rs @@ -0,0 +1,4 @@ +fn main() { + let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff; + //~^ ERROR integer literal is too large +} diff --git a/src/test/ui/parser/issues/issue-5544-b.stderr b/src/test/ui/parser/issues/issue-5544-b.stderr new file mode 100644 index 000000000..7df212ded --- /dev/null +++ b/src/test/ui/parser/issues/issue-5544-b.stderr @@ -0,0 +1,8 @@ +error: integer literal is too large + --> $DIR/issue-5544-b.rs:2:19 + | +LL | let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-56031.rs b/src/test/ui/parser/issues/issue-56031.rs new file mode 100644 index 000000000..b68f56814 --- /dev/null +++ b/src/test/ui/parser/issues/issue-56031.rs @@ -0,0 +1,6 @@ +struct T; + +impl for T {} +//~^ ERROR missing trait in a trait impl + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-56031.stderr b/src/test/ui/parser/issues/issue-56031.stderr new file mode 100644 index 000000000..2fa05dd2d --- /dev/null +++ b/src/test/ui/parser/issues/issue-56031.stderr @@ -0,0 +1,18 @@ +error: missing trait in a trait impl + --> $DIR/issue-56031.rs:3:5 + | +LL | impl for T {} + | ^ + | +help: add a trait here + | +LL | impl Trait for T {} + | +++++ +help: for an inherent impl, drop this `for` + | +LL - impl for T {} +LL + impl T {} + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-57198.rs b/src/test/ui/parser/issues/issue-57198.rs new file mode 100644 index 000000000..714a46cbc --- /dev/null +++ b/src/test/ui/parser/issues/issue-57198.rs @@ -0,0 +1,8 @@ +mod m { + pub fn r#for() {} +} + +fn main() { + m::for(); + //~^ ERROR expected identifier, found keyword `for` +} diff --git a/src/test/ui/parser/issues/issue-57198.stderr b/src/test/ui/parser/issues/issue-57198.stderr new file mode 100644 index 000000000..dd70b4022 --- /dev/null +++ b/src/test/ui/parser/issues/issue-57198.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `for` + --> $DIR/issue-57198.rs:6:8 + | +LL | m::for(); + | ^^^ expected identifier, found keyword + | +help: escape `for` to use it as an identifier + | +LL | m::r#for(); + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-57684.fixed b/src/test/ui/parser/issues/issue-57684.fixed new file mode 100644 index 000000000..4a432206d --- /dev/null +++ b/src/test/ui/parser/issues/issue-57684.fixed @@ -0,0 +1,37 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted when a `=` character is used to initialize +// a struct field when a `:` is expected. +// +// ``` +// error: struct fields are initialized with a colon +// --> $DIR/issue-57684.rs:12:20 +// | +// LL | let _ = X { f1 = 5 }; +// | ^ help: replace equals symbol with a colon: `:` +// ``` + +struct X { + f1: i32, +} + +struct Y { + f1: i32, + f2: i32, + f3: i32, +} + +fn main() { + let _ = X { f1: 5 }; + //~^ ERROR expected `:`, found `=` + + let f3 = 3; + let _ = Y { + f1: 5, + //~^ ERROR expected `:`, found `=` + f2: 4, + f3, + }; +} diff --git a/src/test/ui/parser/issues/issue-57684.rs b/src/test/ui/parser/issues/issue-57684.rs new file mode 100644 index 000000000..7a62785e3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-57684.rs @@ -0,0 +1,37 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted when a `=` character is used to initialize +// a struct field when a `:` is expected. +// +// ``` +// error: struct fields are initialized with a colon +// --> $DIR/issue-57684.rs:12:20 +// | +// LL | let _ = X { f1 = 5 }; +// | ^ help: replace equals symbol with a colon: `:` +// ``` + +struct X { + f1: i32, +} + +struct Y { + f1: i32, + f2: i32, + f3: i32, +} + +fn main() { + let _ = X { f1 = 5 }; + //~^ ERROR expected `:`, found `=` + + let f3 = 3; + let _ = Y { + f1 = 5, + //~^ ERROR expected `:`, found `=` + f2: 4, + f3, + }; +} diff --git a/src/test/ui/parser/issues/issue-57684.stderr b/src/test/ui/parser/issues/issue-57684.stderr new file mode 100644 index 000000000..514bbffde --- /dev/null +++ b/src/test/ui/parser/issues/issue-57684.stderr @@ -0,0 +1,18 @@ +error: expected `:`, found `=` + --> $DIR/issue-57684.rs:27:20 + | +LL | let _ = X { f1 = 5 }; + | -^ + | | + | help: replace equals symbol with a colon: `:` + +error: expected `:`, found `=` + --> $DIR/issue-57684.rs:32:12 + | +LL | f1 = 5, + | -^ + | | + | help: replace equals symbol with a colon: `:` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-57819.fixed b/src/test/ui/parser/issues/issue-57819.fixed new file mode 100644 index 000000000..3fab21db2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-57819.fixed @@ -0,0 +1,47 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>(); +// ^^ help: remove extra angle brackets +// ``` + +trait Foo { + type Output; +} + +fn foo<T: Foo>() { + // More complex cases with more than one correct leading `<` character: + + bar::<<T as Foo>::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<T as Foo>::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<T as Foo>::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<T as Foo>::Output>(); +} + +fn bar<T>() {} + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); +} diff --git a/src/test/ui/parser/issues/issue-57819.rs b/src/test/ui/parser/issues/issue-57819.rs new file mode 100644 index 000000000..5cafbf439 --- /dev/null +++ b/src/test/ui/parser/issues/issue-57819.rs @@ -0,0 +1,47 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>(); +// ^^ help: remove extra angle brackets +// ``` + +trait Foo { + type Output; +} + +fn foo<T: Foo>() { + // More complex cases with more than one correct leading `<` character: + + bar::<<<<<T as Foo>::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<<<T as Foo>::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<<T as Foo>::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<T as Foo>::Output>(); +} + +fn bar<T>() {} + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::<<<<<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<<<<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<<Vec<usize>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>(); +} diff --git a/src/test/ui/parser/issues/issue-57819.stderr b/src/test/ui/parser/issues/issue-57819.stderr new file mode 100644 index 000000000..493e9835b --- /dev/null +++ b/src/test/ui/parser/issues/issue-57819.stderr @@ -0,0 +1,44 @@ +error: unmatched angle brackets + --> $DIR/issue-57819.rs:19:10 + | +LL | bar::<<<<<T as Foo>::Output>(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:22:10 + | +LL | bar::<<<<T as Foo>::Output>(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-57819.rs:25:10 + | +LL | bar::<<<T as Foo>::Output>(); + | ^ help: remove extra angle bracket + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:34:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<<<<Vec<usize>>(); + | ^^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:37:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<<<Vec<usize>>(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:40:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-57819.rs:43:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<Vec<usize>>(); + | ^ help: remove extra angle bracket + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/issues/issue-5806.rs b/src/test/ui/parser/issues/issue-5806.rs new file mode 100644 index 000000000..b694642a9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-5806.rs @@ -0,0 +1,7 @@ +// normalize-stderr-test: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG (" +// normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" + +#[path = "../parser"] +mod foo; //~ ERROR couldn't read + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-5806.stderr b/src/test/ui/parser/issues/issue-5806.stderr new file mode 100644 index 000000000..bdb5c91ff --- /dev/null +++ b/src/test/ui/parser/issues/issue-5806.stderr @@ -0,0 +1,8 @@ +error: couldn't read $DIR/../parser: $ACCESS_DENIED_MSG (os error $ACCESS_DENIED_CODE) + --> $DIR/issue-5806.rs:5:1 + | +LL | mod foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs new file mode 100644 index 000000000..25699f9fe --- /dev/null +++ b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs @@ -0,0 +1,4 @@ +// Fixed in #66054. +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 2 previous errors +#[Ѕ
\ No newline at end of file diff --git a/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr new file mode 100644 index 000000000..8a44ee761 --- /dev/null +++ b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr @@ -0,0 +1,16 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-58094-missing-right-square-bracket.rs:4:4 + | +LL | #[Ѕ + | - ^ + | | + | unclosed delimiter + +error: expected item after attributes + --> $DIR/issue-58094-missing-right-square-bracket.rs:4:1 + | +LL | #[Ѕ + | ^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-58856-1.rs b/src/test/ui/parser/issues/issue-58856-1.rs new file mode 100644 index 000000000..ea80eb871 --- /dev/null +++ b/src/test/ui/parser/issues/issue-58856-1.rs @@ -0,0 +1,8 @@ +impl A { + //~^ ERROR cannot find type `A` in this scope + fn b(self> + //~^ ERROR expected one of `)`, `,`, or `:`, found `>` + //~| ERROR expected one of `->`, `where`, or `{`, found `>` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-58856-1.stderr b/src/test/ui/parser/issues/issue-58856-1.stderr new file mode 100644 index 000000000..96151f3fe --- /dev/null +++ b/src/test/ui/parser/issues/issue-58856-1.stderr @@ -0,0 +1,29 @@ +error: expected one of `)`, `,`, or `:`, found `>` + --> $DIR/issue-58856-1.rs:3:9 + | +LL | fn b(self> + | ^ ^ help: `)` may belong here + | | + | unclosed delimiter + +error: expected one of `->`, `where`, or `{`, found `>` + --> $DIR/issue-58856-1.rs:3:14 + | +LL | impl A { + | - while parsing this item list starting here +LL | +LL | fn b(self> + | ^ expected one of `->`, `where`, or `{` +... +LL | } + | - the item list ends here + +error[E0412]: cannot find type `A` in this scope + --> $DIR/issue-58856-1.rs:1:6 + | +LL | impl A { + | ^ not found in this scope + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/parser/issues/issue-58856-2.rs b/src/test/ui/parser/issues/issue-58856-2.rs new file mode 100644 index 000000000..9356d57b0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-58856-2.rs @@ -0,0 +1,14 @@ +struct Empty; + +trait Howness {} + +impl Howness for () { + fn how_are_you(&self -> Empty { + //~^ ERROR expected one of `)` or `,`, found `->` + //~| ERROR method `how_are_you` is not a member of trait `Howness` + Empty + } +} +//~^ ERROR non-item in item list + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-58856-2.stderr b/src/test/ui/parser/issues/issue-58856-2.stderr new file mode 100644 index 000000000..627dd3890 --- /dev/null +++ b/src/test/ui/parser/issues/issue-58856-2.stderr @@ -0,0 +1,34 @@ +error: expected one of `)` or `,`, found `->` + --> $DIR/issue-58856-2.rs:6:19 + | +LL | fn how_are_you(&self -> Empty { + | ^ -^^ + | | | + | | help: `)` may belong here + | unclosed delimiter + +error: non-item in item list + --> $DIR/issue-58856-2.rs:11:1 + | +LL | impl Howness for () { + | - item list starts here +... +LL | } + | ^ + | | + | non-item starts here + | item list ends here + +error[E0407]: method `how_are_you` is not a member of trait `Howness` + --> $DIR/issue-58856-2.rs:6:5 + | +LL | / fn how_are_you(&self -> Empty { +LL | | +LL | | +LL | | Empty +LL | | } + | |_____^ not a member of trait `Howness` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0407`. diff --git a/src/test/ui/parser/issues/issue-59418.rs b/src/test/ui/parser/issues/issue-59418.rs new file mode 100644 index 000000000..0fa191d4a --- /dev/null +++ b/src/test/ui/parser/issues/issue-59418.rs @@ -0,0 +1,18 @@ +struct X(i32,i32,i32); + +fn main() { + let a = X(1, 2, 3); + let b = a.1suffix; + //~^ ERROR suffixes on a tuple index are invalid + println!("{}", b); + let c = (1, 2, 3); + let d = c.1suffix; + //~^ ERROR suffixes on a tuple index are invalid + println!("{}", d); + let s = X { 0suffix: 0, 1: 1, 2: 2 }; + //~^ ERROR suffixes on a tuple index are invalid + match s { + X { 0suffix: _, .. } => {} + //~^ ERROR suffixes on a tuple index are invalid + } +} diff --git a/src/test/ui/parser/issues/issue-59418.stderr b/src/test/ui/parser/issues/issue-59418.stderr new file mode 100644 index 000000000..347051e9f --- /dev/null +++ b/src/test/ui/parser/issues/issue-59418.stderr @@ -0,0 +1,26 @@ +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:5:15 + | +LL | let b = a.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:9:15 + | +LL | let d = c.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:12:17 + | +LL | let s = X { 0suffix: 0, 1: 1, 2: 2 }; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:15:13 + | +LL | X { 0suffix: _, .. } => {} + | ^^^^^^^ invalid suffix `suffix` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/issues/issue-60075.rs b/src/test/ui/parser/issues/issue-60075.rs new file mode 100644 index 000000000..e89d78ee8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-60075.rs @@ -0,0 +1,11 @@ +fn main() {} + +trait T { + fn qux() -> Option<usize> { + let _ = if true { + }); +//~^ ERROR non-item in item list +//~| ERROR mismatched closing delimiter: `)` +//~| ERROR expected one of `.`, `;` + Some(4) + } diff --git a/src/test/ui/parser/issues/issue-60075.stderr b/src/test/ui/parser/issues/issue-60075.stderr new file mode 100644 index 000000000..210ef700c --- /dev/null +++ b/src/test/ui/parser/issues/issue-60075.stderr @@ -0,0 +1,29 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}` + --> $DIR/issue-60075.rs:6:10 + | +LL | }); + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: non-item in item list + --> $DIR/issue-60075.rs:6:11 + | +LL | trait T { + | - item list starts here +... +LL | }); + | ^ non-item starts here +... +LL | } + | - item list ends here + +error: mismatched closing delimiter: `)` + --> $DIR/issue-60075.rs:4:31 + | +LL | fn qux() -> Option<usize> { + | ^ unclosed delimiter +LL | let _ = if true { +LL | }); + | ^ mismatched closing delimiter + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-62524.rs b/src/test/ui/parser/issues/issue-62524.rs new file mode 100644 index 000000000..5259dfe2e --- /dev/null +++ b/src/test/ui/parser/issues/issue-62524.rs @@ -0,0 +1,6 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 3 previous errors +#![allow(uncommon_codepoints)] + +y![ +Ϥ,
\ No newline at end of file diff --git a/src/test/ui/parser/issues/issue-62524.stderr b/src/test/ui/parser/issues/issue-62524.stderr new file mode 100644 index 000000000..55eed0402 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62524.stderr @@ -0,0 +1,33 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-62524.rs:6:3 + | +LL | y![ + | - unclosed delimiter +LL | Ϥ, + | ^ + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/issue-62524.rs:5:3 + | +LL | y![ + | ___^ +LL | | Ϥ, + | |__^ + | +help: change the delimiters to curly braces + | +LL | y! { /* items */ } + | ~~~~~~~~~~~~~~~ +help: add a semicolon + | +LL | Ϥ,; + | + + +error: cannot find macro `y` in this scope + --> $DIR/issue-62524.rs:5:1 + | +LL | y![ + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-62546.rs b/src/test/ui/parser/issues/issue-62546.rs new file mode 100644 index 000000000..f06b65058 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62546.rs @@ -0,0 +1,3 @@ +pub t(# +//~^ ERROR missing `fn` or `struct` for function or struct definition +//~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/issues/issue-62546.stderr b/src/test/ui/parser/issues/issue-62546.stderr new file mode 100644 index 000000000..32c61391e --- /dev/null +++ b/src/test/ui/parser/issues/issue-62546.stderr @@ -0,0 +1,17 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-62546.rs:3:52 + | +LL | pub t(# + | - unclosed delimiter +LL | +LL | + | ^ + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/issue-62546.rs:1:4 + | +LL | pub t(# + | ---^- help: if you meant to call a macro, try: `t!` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-62554.rs b/src/test/ui/parser/issues/issue-62554.rs new file mode 100644 index 000000000..cfd02183c --- /dev/null +++ b/src/test/ui/parser/issues/issue-62554.rs @@ -0,0 +1,6 @@ +// error-pattern:this file contains an unclosed delimiter +// error-pattern:xpected `{`, found `macro_rules` + +fn main() {} + +fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { diff --git a/src/test/ui/parser/issues/issue-62554.stderr b/src/test/ui/parser/issues/issue-62554.stderr new file mode 100644 index 000000000..9e62572e3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62554.stderr @@ -0,0 +1,73 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-62554.rs:6:89 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - ^ + | | | | | | + | | | | | unclosed delimiter + | | | | unclosed delimiter + | | | unclosed delimiter + | unclosed delimiter unclosed delimiter + +error: expected `{`, found `macro_rules` + --> $DIR/issue-62554.rs:6:23 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | ^^^^^^^^^^^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-62554.rs:6:20 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | ^^ +help: try placing this code inside a block + | +LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { } + | + + + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issues/issue-62660.rs b/src/test/ui/parser/issues/issue-62660.rs new file mode 100644 index 000000000..33c8a9fa3 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62660.rs @@ -0,0 +1,11 @@ +// Regression test for issue #62660: if a receiver's type does not +// successfully parse, emit the correct error instead of ICE-ing the compiler. + +struct Foo; + +impl Foo { + pub fn foo(_: i32, self: Box<Self) {} + //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-62660.stderr b/src/test/ui/parser/issues/issue-62660.stderr new file mode 100644 index 000000000..14c0bdcb1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62660.stderr @@ -0,0 +1,13 @@ +error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)` + --> $DIR/issue-62660.rs:7:38 + | +LL | pub fn foo(_: i32, self: Box<Self) {} + | ^ expected one of 7 possible tokens + | +help: you might have meant to end the type parameters here + | +LL | pub fn foo(_: i32, self: Box<Self>) {} + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-62881.rs b/src/test/ui/parser/issues/issue-62881.rs new file mode 100644 index 000000000..b9204595f --- /dev/null +++ b/src/test/ui/parser/issues/issue-62881.rs @@ -0,0 +1,6 @@ +fn main() {} + +fn f() -> isize { fn f() -> isize {} pub f< +//~^ ERROR missing `fn` or `struct` for function or struct definition +//~| ERROR mismatched types +//~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/issues/issue-62881.stderr b/src/test/ui/parser/issues/issue-62881.stderr new file mode 100644 index 000000000..87be69baa --- /dev/null +++ b/src/test/ui/parser/issues/issue-62881.stderr @@ -0,0 +1,26 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-62881.rs:6:52 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | - unclosed delimiter +... +LL | + | ^ + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/issue-62881.rs:3:41 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | ^ + +error[E0308]: mismatched types + --> $DIR/issue-62881.rs:3:29 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | - ^^^^^ expected `isize`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-62894.rs b/src/test/ui/parser/issues/issue-62894.rs new file mode 100644 index 000000000..b9c0bf834 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62894.rs @@ -0,0 +1,7 @@ +// Regression test for #62894, shouldn't crash. +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn` + +fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-62894.stderr b/src/test/ui/parser/issues/issue-62894.stderr new file mode 100644 index 000000000..ae8992691 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62894.stderr @@ -0,0 +1,52 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-62894.rs:7:14 + | +LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! + | - - - unclosed delimiter + | | | + | | unclosed delimiter + | unclosed delimiter +LL | +LL | fn main() {} + | ^ + +error: this file contains an unclosed delimiter + --> $DIR/issue-62894.rs:7:14 + | +LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! + | - - - unclosed delimiter + | | | + | | unclosed delimiter + | unclosed delimiter +LL | +LL | fn main() {} + | ^ + +error: this file contains an unclosed delimiter + --> $DIR/issue-62894.rs:7:14 + | +LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! + | - - - unclosed delimiter + | | | + | | unclosed delimiter + | unclosed delimiter +LL | +LL | fn main() {} + | ^ + +error: expected one of `(`, `[`, or `{`, found keyword `fn` + --> $DIR/issue-62894.rs:7:1 + | +LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! + | - expected one of `(`, `[`, or `{` +LL | +LL | fn main() {} + | ^^ unexpected token + | + ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | ($left:expr, $right:expr $(,)?) => { + | ---------- while parsing argument for this `expr` macro fragment + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/issues/issue-62895.rs b/src/test/ui/parser/issues/issue-62895.rs new file mode 100644 index 000000000..53f17405d --- /dev/null +++ b/src/test/ui/parser/issues/issue-62895.rs @@ -0,0 +1,11 @@ +fn main() {} + +fn v() -> isize { //~ ERROR mismatched types +mod _ { //~ ERROR expected identifier +pub fn g() -> isizee { //~ ERROR cannot find type `isizee` in this scope +mod _ { //~ ERROR expected identifier +pub g() -> is //~ ERROR missing `fn` for function definition +(), w20); +} +(), w20); //~ ERROR expected item, found `;` +} diff --git a/src/test/ui/parser/issues/issue-62895.stderr b/src/test/ui/parser/issues/issue-62895.stderr new file mode 100644 index 000000000..2e7e500f4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62895.stderr @@ -0,0 +1,47 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-62895.rs:4:5 + | +LL | mod _ { + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-62895.rs:6:5 + | +LL | mod _ { + | ^ expected identifier, found reserved identifier + +error: missing `fn` for function definition + --> $DIR/issue-62895.rs:7:4 + | +LL | pub g() -> is + | ^^^^ + | +help: add `fn` here to parse `g` as a public function + | +LL | pub fn g() -> is + | ++ + +error: expected item, found `;` + --> $DIR/issue-62895.rs:10:9 + | +LL | (), w20); + | ^ help: remove this semicolon + +error[E0412]: cannot find type `isizee` in this scope + --> $DIR/issue-62895.rs:5:15 + | +LL | pub fn g() -> isizee { + | ^^^^^^ help: a builtin type with a similar name exists: `isize` + +error[E0308]: mismatched types + --> $DIR/issue-62895.rs:3:11 + | +LL | fn v() -> isize { + | - ^^^^^ expected `isize`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-62913.rs b/src/test/ui/parser/issues/issue-62913.rs new file mode 100644 index 000000000..0db06f636 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62913.rs @@ -0,0 +1,4 @@ +"\u\\" +//~^ ERROR incorrect unicode escape sequence +//~| ERROR invalid trailing slash in literal +//~| ERROR expected item, found `"\u\\"` diff --git a/src/test/ui/parser/issues/issue-62913.stderr b/src/test/ui/parser/issues/issue-62913.stderr new file mode 100644 index 000000000..6f385e8dc --- /dev/null +++ b/src/test/ui/parser/issues/issue-62913.stderr @@ -0,0 +1,22 @@ +error: incorrect unicode escape sequence + --> $DIR/issue-62913.rs:1:2 + | +LL | "\u\" + | ^^^ incorrect unicode escape sequence + | + = help: format of unicode escape sequences is `\u{...}` + +error: invalid trailing slash in literal + --> $DIR/issue-62913.rs:1:5 + | +LL | "\u\" + | ^ invalid trailing slash in literal + +error: expected item, found `"\u\"` + --> $DIR/issue-62913.rs:1:1 + | +LL | "\u\" + | ^^^^^^ expected item + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-62973.rs b/src/test/ui/parser/issues/issue-62973.rs new file mode 100644 index 000000000..1c5d0c6f8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62973.rs @@ -0,0 +1,8 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 7 previous errors + +fn main() {} + +fn p() { match s { v, E { [) {) } + + diff --git a/src/test/ui/parser/issues/issue-62973.stderr b/src/test/ui/parser/issues/issue-62973.stderr new file mode 100644 index 000000000..4737bc718 --- /dev/null +++ b/src/test/ui/parser/issues/issue-62973.stderr @@ -0,0 +1,83 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-62973.rs:8:2 + | +LL | fn p() { match s { v, E { [) {) } + | - - unclosed delimiter + | | + | unclosed delimiter +LL | +LL | + | ^ + +error: this file contains an unclosed delimiter + --> $DIR/issue-62973.rs:8:2 + | +LL | fn p() { match s { v, E { [) {) } + | - - unclosed delimiter + | | + | unclosed delimiter +LL | +LL | + | ^ + +error: expected one of `,`, `:`, or `}`, found `{` + --> $DIR/issue-62973.rs:6:8 + | +LL | fn p() { match s { v, E { [) {) } + | ^ - ^ expected one of `,`, `:`, or `}` + | | | + | | while parsing this struct + | unclosed delimiter + | +help: `}` may belong here + | +LL | fn p() { match s { v, E} { [) {) } + | + +help: try naming a field + | +LL | fn p() { match s { v, E: E { [) {) } + | ++ + +error: struct literals are not allowed here + --> $DIR/issue-62973.rs:6:16 + | +LL | fn p() { match s { v, E { [) {) } + | ________________^ +LL | | +LL | | + | |_^ + | +help: surround the struct literal with parentheses + | +LL ~ fn p() { match (s { v, E { [) {) } +LL | +LL ~ ) + | + +error: expected one of `.`, `?`, `{`, or an operator, found `}` + --> $DIR/issue-62973.rs:8:2 + | +LL | fn p() { match s { v, E { [) {) } + | ----- while parsing this `match` expression +LL | +LL | + | ^ expected one of `.`, `?`, `{`, or an operator + +error: mismatched closing delimiter: `)` + --> $DIR/issue-62973.rs:6:27 + | +LL | fn p() { match s { v, E { [) {) } + | ^^ mismatched closing delimiter + | | + | unclosed delimiter + +error: mismatched closing delimiter: `)` + --> $DIR/issue-62973.rs:6:30 + | +LL | fn p() { match s { v, E { [) {) } + | ^^ mismatched closing delimiter + | | + | unclosed delimiter + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs b/src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs new file mode 100644 index 000000000..8efb3c73f --- /dev/null +++ b/src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] + +#![allow(ellipsis_inclusive_range_patterns)] + +fn main() { + macro_rules! mac_expr { + ($e:expr) => { + if let 2...$e = 3 {} + if let 2..=$e = 3 {} + if let 2..$e = 3 {} + if let ..$e = 3 {} + if let ..=$e = 3 {} + if let $e.. = 5 {} + if let $e..5 = 4 {} + if let $e..=5 = 4 {} + } + } + mac_expr!(4); +} diff --git a/src/test/ui/parser/issues/issue-63116.rs b/src/test/ui/parser/issues/issue-63116.rs new file mode 100644 index 000000000..430bc1d71 --- /dev/null +++ b/src/test/ui/parser/issues/issue-63116.rs @@ -0,0 +1,3 @@ +// fixed by #66361 +// error-pattern: aborting due to 3 previous errors +impl W <s(f;Y(;] diff --git a/src/test/ui/parser/issues/issue-63116.stderr b/src/test/ui/parser/issues/issue-63116.stderr new file mode 100644 index 000000000..cfdd99d14 --- /dev/null +++ b/src/test/ui/parser/issues/issue-63116.stderr @@ -0,0 +1,24 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-63116.rs:3:18 + | +LL | impl W <s(f;Y(;] + | - ^ + | | + | unclosed delimiter + +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `;` + --> $DIR/issue-63116.rs:3:12 + | +LL | impl W <s(f;Y(;] + | ^ expected one of 7 possible tokens + +error: mismatched closing delimiter: `]` + --> $DIR/issue-63116.rs:3:14 + | +LL | impl W <s(f;Y(;] + | ^ ^ mismatched closing delimiter + | | + | unclosed delimiter + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-63135.rs b/src/test/ui/parser/issues/issue-63135.rs new file mode 100644 index 000000000..a5a8de854 --- /dev/null +++ b/src/test/ui/parser/issues/issue-63135.rs @@ -0,0 +1,3 @@ +// error-pattern: aborting due to 5 previous errors + +fn i(n{...,f # diff --git a/src/test/ui/parser/issues/issue-63135.stderr b/src/test/ui/parser/issues/issue-63135.stderr new file mode 100644 index 000000000..80e9ac5be --- /dev/null +++ b/src/test/ui/parser/issues/issue-63135.stderr @@ -0,0 +1,43 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-63135.rs:3:16 + | +LL | fn i(n{...,f # + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-63135.rs:3:16 + | +LL | fn i(n{...,f # + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: expected field pattern, found `...` + --> $DIR/issue-63135.rs:3:8 + | +LL | fn i(n{...,f # + | ^^^ help: to omit remaining fields, use one fewer `.`: `..` + +error: expected `}`, found `,` + --> $DIR/issue-63135.rs:3:11 + | +LL | fn i(n{...,f # + | ---^ + | | | + | | expected `}` + | `..` must be at the end and cannot have a trailing comma + +error: expected one of `!` or `[`, found `}` + --> $DIR/issue-63135.rs:3:16 + | +LL | fn i(n{...,f # + | - ^ expected one of `!` or `[` + | | + | while parsing the fields for this pattern + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/parser/issues/issue-64732.rs b/src/test/ui/parser/issues/issue-64732.rs new file mode 100644 index 000000000..2db51ea60 --- /dev/null +++ b/src/test/ui/parser/issues/issue-64732.rs @@ -0,0 +1,9 @@ +#![allow(unused)] +fn main() { + let _foo = b'hello\0'; + //~^ ERROR character literal may only contain one codepoint + //~| HELP if you meant to write a byte string literal, use double quotes + let _bar = 'hello'; + //~^ ERROR character literal may only contain one codepoint + //~| HELP if you meant to write a `str` literal, use double quotes +} diff --git a/src/test/ui/parser/issues/issue-64732.stderr b/src/test/ui/parser/issues/issue-64732.stderr new file mode 100644 index 000000000..804625493 --- /dev/null +++ b/src/test/ui/parser/issues/issue-64732.stderr @@ -0,0 +1,24 @@ +error: character literal may only contain one codepoint + --> $DIR/issue-64732.rs:3:16 + | +LL | let _foo = b'hello\0'; + | ^^^^^^^^^^ + | +help: if you meant to write a byte string literal, use double quotes + | +LL | let _foo = b"hello\0"; + | ~~~~~~~~~~ + +error: character literal may only contain one codepoint + --> $DIR/issue-64732.rs:6:16 + | +LL | let _bar = 'hello'; + | ^^^^^^^ + | +help: if you meant to write a `str` literal, use double quotes + | +LL | let _bar = "hello"; + | ~~~~~~~ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs new file mode 100644 index 000000000..ef89e31d8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs @@ -0,0 +1,28 @@ +// check-pass + +// Here we check that a `:vis` macro matcher subsititued for the empty visibility +// (`VisibilityKind::Inherited`) is accepted when used before an enum variant. + +fn main() {} + +macro_rules! mac_variant { + ($vis:vis MARKER) => { + enum Enum { + $vis Unit, + + $vis Tuple(u8, u16), + + $vis Struct { f: u8 }, + } + } +} + +mac_variant!(MARKER); + +// We also accept visibilities on variants syntactically but not semantically. +#[cfg(FALSE)] +enum E { + pub U, + pub(crate) T(u8), + pub(super) T { f: String } +} diff --git a/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs new file mode 100644 index 000000000..b08767b21 --- /dev/null +++ b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs @@ -0,0 +1,28 @@ +// check-pass + +// Here we check that a `:vis` macro matcher subsititued for the empty visibility +// (`VisibilityKind::Inherited`) is accepted when used before an item in a trait. + +fn main() {} + +macro_rules! mac_in_trait { + ($vis:vis MARKER) => { + $vis fn beta() {} + + $vis const GAMMA: u8; + + $vis type Delta; + } +} + +trait Alpha { + mac_in_trait!(MARKER); +} + +// We also accept visibilities on items in traits syntactically but not semantically. +#[cfg(FALSE)] +trait Foo { + pub fn bar(); + pub(crate) type baz; + pub(super) const QUUX: u8; +} diff --git a/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs new file mode 100644 index 000000000..30f3781bf --- /dev/null +++ b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs @@ -0,0 +1,26 @@ +// Regression test; used to ICE with 'visit_mac_call disabled by default' due to a +// `MutVisitor` in `fn make_all_value_bindings_mutable` (`parse/parser/pat.rs`). + +macro_rules! mac1 { + ($eval:expr) => { + let mut $eval = (); + //~^ ERROR `mut` must be followed by a named binding + }; +} + +macro_rules! mac2 { + ($eval:pat) => { + let mut $eval = (); + //~^ ERROR `mut` must be followed by a named binding + //~| ERROR expected identifier, found `does_not_exist!()` + }; +} + +fn foo() { + mac1! { does_not_exist!() } + //~^ ERROR cannot find macro `does_not_exist` in this scope + mac2! { does_not_exist!() } + //~^ ERROR cannot find macro `does_not_exist` in this scope +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr new file mode 100644 index 000000000..8c032e588 --- /dev/null +++ b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr @@ -0,0 +1,49 @@ +error: `mut` must be followed by a named binding + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:6:13 + | +LL | let mut $eval = (); + | ^^^^^^^^^ help: remove the `mut` prefix: `does_not_exist!()` +... +LL | mac1! { does_not_exist!() } + | --------------------------- in this macro invocation + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + = note: this error originates in the macro `mac1` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected identifier, found `does_not_exist!()` + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:17 + | +LL | let mut $eval = (); + | ^^^^^ expected identifier +... +LL | mac2! { does_not_exist!() } + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `mut` must be followed by a named binding + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:13 + | +LL | let mut $eval = (); + | ^^^ help: remove the `mut` prefix: `does_not_exist!()` +... +LL | mac2! { does_not_exist!() } + | --------------------------- in this macro invocation + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot find macro `does_not_exist` in this scope + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13 + | +LL | mac2! { does_not_exist!() } + | ^^^^^^^^^^^^^^ + +error: cannot find macro `does_not_exist` in this scope + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13 + | +LL | mac1! { does_not_exist!() } + | ^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs new file mode 100644 index 000000000..c1826f8ca --- /dev/null +++ b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs @@ -0,0 +1,21 @@ +fn main() { + auto n = 0;//~ ERROR invalid variable declaration + //~^ HELP write `let` instead of `auto` to introduce a new variable + auto m;//~ ERROR invalid variable declaration + //~^ HELP write `let` instead of `auto` to introduce a new variable + m = 0; + + var n = 0;//~ ERROR invalid variable declaration + //~^ HELP write `let` instead of `var` to introduce a new variable + var m;//~ ERROR invalid variable declaration + //~^ HELP write `let` instead of `var` to introduce a new variable + m = 0; + + mut n = 0;//~ ERROR invalid variable declaration + //~^ HELP missing keyword + mut var;//~ ERROR invalid variable declaration + //~^ HELP missing keyword + var = 0; + + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr new file mode 100644 index 000000000..0a88dd2c4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr @@ -0,0 +1,67 @@ +error: invalid variable declaration + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:2:5 + | +LL | auto n = 0; + | ^^^^ + | +help: write `let` instead of `auto` to introduce a new variable + | +LL | let n = 0; + | ~~~ + +error: invalid variable declaration + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:4:5 + | +LL | auto m; + | ^^^^ + | +help: write `let` instead of `auto` to introduce a new variable + | +LL | let m; + | ~~~ + +error: invalid variable declaration + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:8:5 + | +LL | var n = 0; + | ^^^ + | +help: write `let` instead of `var` to introduce a new variable + | +LL | let n = 0; + | ~~~ + +error: invalid variable declaration + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:10:5 + | +LL | var m; + | ^^^ + | +help: write `let` instead of `var` to introduce a new variable + | +LL | let m; + | ~~~ + +error: invalid variable declaration + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:14:5 + | +LL | mut n = 0; + | ^^^ help: missing keyword: `let mut` + +error: invalid variable declaration + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:16:5 + | +LL | mut var; + | ^^^ help: missing keyword: `let mut` + +error[E0308]: mismatched types + --> $DIR/issue-65257-invalid-var-decl-recovery.rs:20:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs b/src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs new file mode 100644 index 000000000..76c07bbfd --- /dev/null +++ b/src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs @@ -0,0 +1,15 @@ +// run-pass + +// Test that failing macro matchers will not cause pre-expansion errors +// even though they use a feature that is pre-expansion gated. + +#[allow(unused_macro_rules)] +macro_rules! m { + ($e:expr) => { 0 }; // This fails on the input below due to `, foo`. + ($e:expr,) => { 1 }; // This also fails to match due to `foo`. + (box $e:expr, foo) => { 2 }; // Successful matcher, we should get `2`. +} + +fn main() { + assert_eq!(2, m!(box 42, foo)); +} diff --git a/src/test/ui/parser/issues/issue-6610.rs b/src/test/ui/parser/issues/issue-6610.rs new file mode 100644 index 000000000..9ed5a6122 --- /dev/null +++ b/src/test/ui/parser/issues/issue-6610.rs @@ -0,0 +1,3 @@ +trait Foo { fn a() } //~ ERROR expected one of `->`, `;`, `where`, or `{`, found `}` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-6610.stderr b/src/test/ui/parser/issues/issue-6610.stderr new file mode 100644 index 000000000..4a3bc7525 --- /dev/null +++ b/src/test/ui/parser/issues/issue-6610.stderr @@ -0,0 +1,10 @@ +error: expected one of `->`, `;`, `where`, or `{`, found `}` + --> $DIR/issue-6610.rs:1:20 + | +LL | trait Foo { fn a() } + | - ^ expected one of `->`, `;`, `where`, or `{` + | | + | while parsing this `fn` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs new file mode 100644 index 000000000..aed428bfc --- /dev/null +++ b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs @@ -0,0 +1,14 @@ +// The problem in #66357 was that the call trace: +// +// - parse_fn_block_decl +// - expect_or +// - unexpected +// - expect_one_of +// - expected_one_of_not_found +// - recover_closing_delimiter +// +// ended up bubbling up `Ok(true)` to `unexpected` which then used `unreachable!()`. + +fn f() { |[](* } +//~^ ERROR expected one of `,` or `:`, found `(` +//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` diff --git a/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr new file mode 100644 index 000000000..6cbab855c --- /dev/null +++ b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr @@ -0,0 +1,16 @@ +error: expected one of `,` or `:`, found `(` + --> $DIR/issue-66357-unexpected-unreachable.rs:12:13 + | +LL | fn f() { |[](* } + | ^ expected one of `,` or `:` + +error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` + --> $DIR/issue-66357-unexpected-unreachable.rs:12:13 + | +LL | fn f() { |[](* } + | ^^ help: `)` may belong here + | | + | unclosed delimiter + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-66473.rs b/src/test/ui/parser/issues/issue-66473.rs Binary files differnew file mode 100644 index 000000000..9db4521bb --- /dev/null +++ b/src/test/ui/parser/issues/issue-66473.rs diff --git a/src/test/ui/parser/issues/issue-66473.stderr b/src/test/ui/parser/issues/issue-66473.stderr Binary files differnew file mode 100644 index 000000000..8a16d7f95 --- /dev/null +++ b/src/test/ui/parser/issues/issue-66473.stderr diff --git a/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed new file mode 100644 index 000000000..95019b278 --- /dev/null +++ b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed @@ -0,0 +1,14 @@ +// run-rustfix + +// In this regression test for #67146, we check that the +// negative outlives bound `!'a` is rejected by the parser. +// This regression was first introduced in PR #57364. + +fn main() {} + +pub fn f1<T>() {} +//~^ ERROR negative bounds are not supported +pub fn f2<'a, T: Ord>() {} +//~^ ERROR negative bounds are not supported +pub fn f3<'a, T: Ord>() {} +//~^ ERROR negative bounds are not supported diff --git a/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs new file mode 100644 index 000000000..82f54f8fa --- /dev/null +++ b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs @@ -0,0 +1,14 @@ +// run-rustfix + +// In this regression test for #67146, we check that the +// negative outlives bound `!'a` is rejected by the parser. +// This regression was first introduced in PR #57364. + +fn main() {} + +pub fn f1<T: !'static>() {} +//~^ ERROR negative bounds are not supported +pub fn f2<'a, T: Ord + !'a>() {} +//~^ ERROR negative bounds are not supported +pub fn f3<'a, T: !'a + Ord>() {} +//~^ ERROR negative bounds are not supported diff --git a/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr new file mode 100644 index 000000000..a4a422948 --- /dev/null +++ b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr @@ -0,0 +1,20 @@ +error: negative bounds are not supported + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:12 + | +LL | pub fn f1<T: !'static>() {} + | ^^^^^^^^^^ negative bounds are not supported + +error: negative bounds are not supported + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:11:22 + | +LL | pub fn f2<'a, T: Ord + !'a>() {} + | ^^^^^ negative bounds are not supported + +error: negative bounds are not supported + --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:13:16 + | +LL | pub fn f3<'a, T: !'a + Ord>() {} + | ^^^^^ negative bounds are not supported + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs new file mode 100644 index 000000000..87222ef4b --- /dev/null +++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs @@ -0,0 +1,35 @@ +mod a { + use std::marker::PhantomData; + + enum Bug { + V = [PhantomData; { [ () ].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + } +} + +mod b { + enum Bug { + V = [Vec::new; { [].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed + } +} + +mod c { + enum Bug { + V = [Vec::new; { [0].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed + } +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr new file mode 100644 index 000000000..85c9fe409 --- /dev/null +++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -0,0 +1,128 @@ +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - ^ ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | ^^^ cannot infer type for type parameter `T` + +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec` + | +help: consider specifying the generic argument + | +LL | V = [Vec::<T>::new; { [0].len() ].len() as isize, + | +++++ + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs new file mode 100644 index 000000000..3c49a5a97 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs @@ -0,0 +1,6 @@ +pub struct Foo { + pub bar: Vec<i32>ö + //~^ ERROR expected `,`, or `}`, found `ö` +} //~ ERROR expected `:`, found `}` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr new file mode 100644 index 000000000..ef365a616 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr @@ -0,0 +1,17 @@ +error: expected `,`, or `}`, found `ö` + --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22 + | +LL | pub bar: Vec<i32>ö + | ^ help: try adding a comma: `,` + +error: expected `:`, found `}` + --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1 + | +LL | pub bar: Vec<i32>ö + | - expected `:` +LL | +LL | } + | ^ unexpected token + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-68629.rs b/src/test/ui/parser/issues/issue-68629.rs Binary files differnew file mode 100644 index 000000000..672a31f12 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68629.rs diff --git a/src/test/ui/parser/issues/issue-68629.stderr b/src/test/ui/parser/issues/issue-68629.stderr Binary files differnew file mode 100644 index 000000000..b2c7dddc8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68629.stderr diff --git a/src/test/ui/parser/issues/issue-68730.rs b/src/test/ui/parser/issues/issue-68730.rs Binary files differnew file mode 100644 index 000000000..20e18b4bc --- /dev/null +++ b/src/test/ui/parser/issues/issue-68730.rs diff --git a/src/test/ui/parser/issues/issue-68730.stderr b/src/test/ui/parser/issues/issue-68730.stderr Binary files differnew file mode 100644 index 000000000..6585a19d9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68730.stderr diff --git a/src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs b/src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs new file mode 100644 index 000000000..7c3dd1d5a --- /dev/null +++ b/src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs @@ -0,0 +1,21 @@ +// Make sure we don't propagate restrictions on trait impl items to items inside them. + +// check-pass +// edition:2018 + +fn main() {} + +trait X { + fn foo(); +} + +impl X for () { + fn foo() { + struct S; + impl S { + pub const X: u8 = 0; + pub const fn bar() {} + async fn qux() {} + } + } +} diff --git a/src/test/ui/parser/issues/issue-68890-2.rs b/src/test/ui/parser/issues/issue-68890-2.rs new file mode 100644 index 000000000..29c123521 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68890-2.rs @@ -0,0 +1,5 @@ +fn main() {} + +type X<'a> = (?'a) +; +//~^ ERROR `?` may only modify trait bounds, not lifetime bounds +//~| ERROR at least one trait is required for an object type diff --git a/src/test/ui/parser/issues/issue-68890-2.stderr b/src/test/ui/parser/issues/issue-68890-2.stderr new file mode 100644 index 000000000..d9fb7beeb --- /dev/null +++ b/src/test/ui/parser/issues/issue-68890-2.stderr @@ -0,0 +1,15 @@ +error: `?` may only modify trait bounds, not lifetime bounds + --> $DIR/issue-68890-2.rs:3:15 + | +LL | type X<'a> = (?'a) +; + | ^ + +error[E0224]: at least one trait is required for an object type + --> $DIR/issue-68890-2.rs:3:14 + | +LL | type X<'a> = (?'a) +; + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/parser/issues/issue-68890.rs b/src/test/ui/parser/issues/issue-68890.rs new file mode 100644 index 000000000..bab4ed7f8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68890.rs @@ -0,0 +1,4 @@ +enum e{A((?'a a+?+l))} +//~^ ERROR `?` may only modify trait bounds, not lifetime bounds +//~| ERROR expected one of `)`, `+`, or `,` +//~| ERROR expected item, found `)` diff --git a/src/test/ui/parser/issues/issue-68890.stderr b/src/test/ui/parser/issues/issue-68890.stderr new file mode 100644 index 000000000..2a3bf6b41 --- /dev/null +++ b/src/test/ui/parser/issues/issue-68890.stderr @@ -0,0 +1,20 @@ +error: `?` may only modify trait bounds, not lifetime bounds + --> $DIR/issue-68890.rs:1:11 + | +LL | enum e{A((?'a a+?+l))} + | ^ + +error: expected one of `)`, `+`, or `,`, found `a` + --> $DIR/issue-68890.rs:1:15 + | +LL | enum e{A((?'a a+?+l))} + | ^ expected one of `)`, `+`, or `,` + +error: expected item, found `)` + --> $DIR/issue-68890.rs:1:21 + | +LL | enum e{A((?'a a+?+l))} + | ^ expected item + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs b/src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs new file mode 100644 index 000000000..aca9d9eb0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs @@ -0,0 +1,16 @@ +// check-pass + +macro_rules! foo { + ($a:literal) => { + bar!($a) + }; +} + +macro_rules! bar { + ($b:literal) => {}; +} + +fn main() { + foo!(-2); + bar!(-2); +} diff --git a/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs new file mode 100644 index 000000000..ca8abd78c --- /dev/null +++ b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs @@ -0,0 +1,7 @@ +struct Foo(i32); + +fn main() { + let Foo(...) = Foo(0); //~ ERROR unexpected `...` + let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...` + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr new file mode 100644 index 000000000..4961e8fc0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr @@ -0,0 +1,29 @@ +error: unexpected `...` + --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:4:13 + | +LL | let Foo(...) = Foo(0); + | ^^^ + | | + | not a valid pattern + | help: for a rest pattern, use `..` instead of `...` + +error: unexpected `...` + --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:5:13 + | +LL | let [_, ..., _] = [0, 1]; + | ^^^ + | | + | not a valid pattern + | help: for a rest pattern, use `..` instead of `...` + +error[E0308]: mismatched types + --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:6:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.fixed b/src/test/ui/parser/issues/issue-70388-without-witness.fixed new file mode 100644 index 000000000..8d981405e --- /dev/null +++ b/src/test/ui/parser/issues/issue-70388-without-witness.fixed @@ -0,0 +1,9 @@ +// run-rustfix +// This is for checking if we can apply suggestions as-is. + +pub struct Foo(#[allow(unused_tuple_struct_fields)] i32); + +fn main() { + let Foo(..) = Foo(0); //~ ERROR unexpected `...` + let [_, .., _] = [0, 1]; //~ ERROR unexpected `...` +} diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.rs b/src/test/ui/parser/issues/issue-70388-without-witness.rs new file mode 100644 index 000000000..bf3607308 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70388-without-witness.rs @@ -0,0 +1,9 @@ +// run-rustfix +// This is for checking if we can apply suggestions as-is. + +pub struct Foo(#[allow(unused_tuple_struct_fields)] i32); + +fn main() { + let Foo(...) = Foo(0); //~ ERROR unexpected `...` + let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...` +} diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.stderr b/src/test/ui/parser/issues/issue-70388-without-witness.stderr new file mode 100644 index 000000000..b750ad4c6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70388-without-witness.stderr @@ -0,0 +1,20 @@ +error: unexpected `...` + --> $DIR/issue-70388-without-witness.rs:7:13 + | +LL | let Foo(...) = Foo(0); + | ^^^ + | | + | not a valid pattern + | help: for a rest pattern, use `..` instead of `...` + +error: unexpected `...` + --> $DIR/issue-70388-without-witness.rs:8:13 + | +LL | let [_, ..., _] = [0, 1]; + | ^^^ + | | + | not a valid pattern + | help: for a rest pattern, use `..` instead of `...` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs new file mode 100644 index 000000000..aeccd0d9f --- /dev/null +++ b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs @@ -0,0 +1,18 @@ +struct S {} + +impl S { + fn foo(&mur Self) {} + //~^ ERROR expected identifier, found keyword `Self` + //~| ERROR expected one of `:`, `@` + //~| ERROR the `Self` constructor can only be used with + fn bar(&'static mur Self) {} + //~^ ERROR unexpected lifetime + //~| ERROR expected identifier, found keyword `Self` + //~| ERROR expected one of `:`, `@` + //~| ERROR the `Self` constructor can only be used with + + fn baz(&mur Self @ _) {} + //~^ ERROR expected one of `:`, `@` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr new file mode 100644 index 000000000..421f14540 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr @@ -0,0 +1,56 @@ +error: expected identifier, found keyword `Self` + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17 + | +LL | fn foo(&mur Self) {} + | ^^^^ expected identifier, found keyword + +error: expected one of `:`, `@`, or `|`, found keyword `Self` + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17 + | +LL | fn foo(&mur Self) {} + | -----^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `<identifier>: <type>` + +error: unexpected lifetime `'static` in pattern + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:13 + | +LL | fn bar(&'static mur Self) {} + | ^^^^^^^ help: remove the lifetime + +error: expected identifier, found keyword `Self` + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25 + | +LL | fn bar(&'static mur Self) {} + | ^^^^ expected identifier, found keyword + +error: expected one of `:`, `@`, or `|`, found keyword `Self` + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25 + | +LL | fn bar(&'static mur Self) {} + | -------------^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `<identifier>: <type>` + +error: expected one of `:`, `@`, or `|`, found keyword `Self` + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:14:17 + | +LL | fn baz(&mur Self @ _) {} + | ^^^^ expected one of `:`, `@`, or `|` + +error: the `Self` constructor can only be used with tuple or unit structs + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17 + | +LL | fn foo(&mur Self) {} + | ^^^^ help: use curly brackets: `Self { /* fields */ }` + +error: the `Self` constructor can only be used with tuple or unit structs + --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25 + | +LL | fn bar(&'static mur Self) {} + | ^^^^ help: use curly brackets: `Self { /* fields */ }` + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs new file mode 100644 index 000000000..9b6dd7db4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs @@ -0,0 +1,3 @@ +fn main() { + expr as fun()(:); //~ ERROR expected expression +} diff --git a/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr new file mode 100644 index 000000000..f03c92e1b --- /dev/null +++ b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr @@ -0,0 +1,8 @@ +error: expected expression, found `:` + --> $DIR/issue-70552-ascription-in-parens-after-call.rs:2:19 + | +LL | expr as fun()(:); + | ^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs new file mode 100644 index 000000000..f560f68f6 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs @@ -0,0 +1,20 @@ +pub enum ErrorHandled { + Reported, + TooGeneric, +} + +impl ErrorHandled { + pub fn assert_reported(self) { + match self { + ErrorHandled::Reported => {} + ErrorHandled::TooGeneric => panic!(), + } + } +} + +fn struct_generic(x: Vec<i32>) { + for v in x { + println!("{}", v); + } + } +} //~ ERROR unexpected closing delimiter: `}` diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr new file mode 100644 index 000000000..39bf113ef --- /dev/null +++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr @@ -0,0 +1,13 @@ +error: unexpected closing delimiter: `}` + --> $DIR/issue-70583-block-is-empty-1.rs:20:1 + | +LL | fn struct_generic(x: Vec<i32>) { + | - this opening brace... +... +LL | } + | - ...matches this closing brace +LL | } + | ^ unexpected closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs new file mode 100644 index 000000000..80f53338a --- /dev/null +++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs @@ -0,0 +1,14 @@ +pub enum ErrorHandled { + Reported, + TooGeneric, +} + +impl ErrorHandled { + pub fn assert_reported(self) { + match self { + ErrorHandled::Reported => {}} + //^~ ERROR block is empty, you might have not meant to close it + ErrorHandled::TooGeneric => panic!(), + } + } +} //~ ERROR unexpected closing delimiter: `}` diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr new file mode 100644 index 000000000..5d37b2164 --- /dev/null +++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr @@ -0,0 +1,11 @@ +error: unexpected closing delimiter: `}` + --> $DIR/issue-70583-block-is-empty-2.rs:14:1 + | +LL | ErrorHandled::Reported => {}} + | -- block is empty, you might have not meant to close it +... +LL | } + | ^ unexpected closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-7222.rs b/src/test/ui/parser/issues/issue-7222.rs new file mode 100644 index 000000000..649073166 --- /dev/null +++ b/src/test/ui/parser/issues/issue-7222.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620 + +pub fn main() { + const FOO: f64 = 10.0; + + match 0.0 { + 0.0 ..= FOO => (), + _ => () + } +} diff --git a/src/test/ui/parser/issues/issue-72253.rs b/src/test/ui/parser/issues/issue-72253.rs new file mode 100644 index 000000000..1446a796f --- /dev/null +++ b/src/test/ui/parser/issues/issue-72253.rs @@ -0,0 +1,6 @@ +fn main() { + let a = std::process::Command::new("echo") + .arg("1") + ,arg("2") //~ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `,` + .output(); +} diff --git a/src/test/ui/parser/issues/issue-72253.stderr b/src/test/ui/parser/issues/issue-72253.stderr new file mode 100644 index 000000000..477fa09f4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-72253.stderr @@ -0,0 +1,10 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `,` + --> $DIR/issue-72253.rs:4:9 + | +LL | .arg("1") + | - expected one of `.`, `;`, `?`, `else`, or an operator +LL | ,arg("2") + | ^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-72373.rs b/src/test/ui/parser/issues/issue-72373.rs new file mode 100644 index 000000000..4da6061c2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-72373.rs @@ -0,0 +1,9 @@ +fn foo(c: &[u32], n: u32) -> u32 { + match *c { + [h, ..] if h > n => 0, + [h, ..] if h == n => 1, + [h, ref ts..] => foo(c, n - h) + foo(ts, n), + //~^ ERROR expected one of `,`, `@`, `]`, or `|`, found `..` + [] => 0, + } +} diff --git a/src/test/ui/parser/issues/issue-72373.stderr b/src/test/ui/parser/issues/issue-72373.stderr new file mode 100644 index 000000000..0bb99a01e --- /dev/null +++ b/src/test/ui/parser/issues/issue-72373.stderr @@ -0,0 +1,13 @@ +error: expected one of `,`, `@`, `]`, or `|`, found `..` + --> $DIR/issue-72373.rs:5:19 + | +LL | [h, ref ts..] => foo(c, n - h) + foo(ts, n), + | ^^ expected one of `,`, `@`, `]`, or `|` + | +help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@` + | +LL | [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n), + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs new file mode 100644 index 000000000..5f731f8db --- /dev/null +++ b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs @@ -0,0 +1,19 @@ +#![crate_type="lib"] +fn x<'a>(x: &mut 'a i32){} //~ ERROR lifetime must precede `mut` + +macro_rules! mac { + ($lt:lifetime) => { + fn w<$lt>(w: &mut $lt i32) {} + //~^ ERROR lifetime must precede `mut` + } +} + +mac!('a); + +// avoid false positives +fn y<'a>(y: &mut 'a + Send) { + //~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a` + //~| ERROR at least one trait is required for an object type + let z = y as &mut 'a + Send; + //~^ ERROR expected value, found trait `Send` +} diff --git a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr new file mode 100644 index 000000000..799bc16bd --- /dev/null +++ b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr @@ -0,0 +1,39 @@ +error: lifetime must precede `mut` + --> $DIR/issue-73568-lifetime-after-mut.rs:2:13 + | +LL | fn x<'a>(x: &mut 'a i32){} + | ^^^^^^^ help: place the lifetime before `mut`: `&'a mut` + +error[E0178]: expected a path on the left-hand side of `+`, not `&mut 'a` + --> $DIR/issue-73568-lifetime-after-mut.rs:14:13 + | +LL | fn y<'a>(y: &mut 'a + Send) { + | ^^^^^^^^^^^^^^ help: try adding parentheses: `&mut ('a + Send)` + +error: lifetime must precede `mut` + --> $DIR/issue-73568-lifetime-after-mut.rs:6:22 + | +LL | fn w<$lt>(w: &mut $lt i32) {} + | ^^^^^^^^ help: place the lifetime before `mut`: `&$lt mut` +... +LL | mac!('a); + | -------- in this macro invocation + | + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0423]: expected value, found trait `Send` + --> $DIR/issue-73568-lifetime-after-mut.rs:17:28 + | +LL | let z = y as &mut 'a + Send; + | ^^^^ not a value + +error[E0224]: at least one trait is required for an object type + --> $DIR/issue-73568-lifetime-after-mut.rs:14:18 + | +LL | fn y<'a>(y: &mut 'a + Send) { + | ^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0178, E0224, E0423. +For more information about an error, try `rustc --explain E0178`. diff --git a/src/test/ui/parser/issues/issue-75599.rs b/src/test/ui/parser/issues/issue-75599.rs new file mode 100644 index 000000000..0857676e4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-75599.rs @@ -0,0 +1,24 @@ +// check-pass +#![allow(non_upper_case_globals)] + +const or: usize = 1; +const and: usize = 2; + +mod or { + pub const X: usize = 3; +} + +mod and { + pub const X: usize = 4; +} + +fn main() { + match 0 { + 0 => {} + or => {} + and => {} + or::X => {} + and::X => {} + _ => {} + } +} diff --git a/src/test/ui/parser/issues/issue-76437-async.rs b/src/test/ui/parser/issues/issue-76437-async.rs new file mode 100644 index 000000000..84ee3dd21 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-async.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + async pub fn t() {} + //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `async` +} diff --git a/src/test/ui/parser/issues/issue-76437-async.stderr b/src/test/ui/parser/issues/issue-76437-async.stderr new file mode 100644 index 000000000..2c9c2a8cf --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-async.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-async.rs:4:11 + | +LL | async pub fn t() {} + | ------^^^ + | | | + | | expected one of `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `async`: `pub async` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs new file mode 100644 index 000000000..f1e06e4ad --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + const async unsafe pub fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub` must come before `const async unsafe` +} diff --git a/src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr new file mode 100644 index 000000000..2e91beda1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-const-async-unsafe.rs:4:24 + | +LL | const async unsafe pub fn t() {} + | -------------------^^^ + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub` must come before `const async unsafe`: `pub const async unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-76437-const-async.rs b/src/test/ui/parser/issues/issue-76437-const-async.rs new file mode 100644 index 000000000..3c789fdcd --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-const-async.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + const async pub fn t() {} + //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `const async` +} diff --git a/src/test/ui/parser/issues/issue-76437-const-async.stderr b/src/test/ui/parser/issues/issue-76437-const-async.stderr new file mode 100644 index 000000000..21b96c14d --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-const-async.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-const-async.rs:4:17 + | +LL | const async pub fn t() {} + | ------------^^^ + | | | + | | expected one of `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const async`: `pub const async` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-76437-const.rs b/src/test/ui/parser/issues/issue-76437-const.rs new file mode 100644 index 000000000..d3815a523 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-const.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + const pub fn t() {} + //~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `const` +} diff --git a/src/test/ui/parser/issues/issue-76437-const.stderr b/src/test/ui/parser/issues/issue-76437-const.stderr new file mode 100644 index 000000000..cf80d9a90 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-const.stderr @@ -0,0 +1,11 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-const.rs:4:11 + | +LL | const pub fn t() {} + | ------^^^ + | | | + | | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const`: `pub const` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs new file mode 100644 index 000000000..daa1d1207 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + unsafe pub(crate) fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub(crate)` must come before `unsafe` +} diff --git a/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr new file mode 100644 index 000000000..fa8f13721 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-pub-crate-unsafe.rs:4:12 + | +LL | unsafe pub(crate) fn t() {} + | -------^^^------- + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub(crate)` must come before `unsafe`: `pub(crate) unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-76437-unsafe.rs b/src/test/ui/parser/issues/issue-76437-unsafe.rs new file mode 100644 index 000000000..785a79a79 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-unsafe.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + unsafe pub fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub` must come before `unsafe` +} diff --git a/src/test/ui/parser/issues/issue-76437-unsafe.stderr b/src/test/ui/parser/issues/issue-76437-unsafe.stderr new file mode 100644 index 000000000..c63292ef8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76437-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-unsafe.rs:4:12 + | +LL | unsafe pub fn t() {} + | -------^^^ + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub` must come before `unsafe`: `pub unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-76597.fixed b/src/test/ui/parser/issues/issue-76597.fixed new file mode 100644 index 000000000..2d7a30b83 --- /dev/null +++ b/src/test/ui/parser/issues/issue-76597.fixed @@ -0,0 +1,11 @@ +// run-rustfix + +#![allow(dead_code)] +#![allow(unused_variables)] +fn f( + x: u8, + y: u8, +) {} +//~^^ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-76597.rs b/src/test/ui/parser/issues/issue-76597.rs new file mode 100644 index 000000000..521b9c64b --- /dev/null +++ b/src/test/ui/parser/issues/issue-76597.rs @@ -0,0 +1,11 @@ +// run-rustfix + +#![allow(dead_code)] +#![allow(unused_variables)] +fn f( + x: u8 + y: u8, +) {} +//~^^ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-76597.stderr b/src/test/ui/parser/issues/issue-76597.stderr new file mode 100644 index 000000000..50b23329f --- /dev/null +++ b/src/test/ui/parser/issues/issue-76597.stderr @@ -0,0 +1,13 @@ +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y` + --> $DIR/issue-76597.rs:7:38 + | +LL | ... x: u8 + | - + | | + | expected one of 7 possible tokens + | help: missing `,` +LL | ... y: u8, + | ^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-7970b.rs b/src/test/ui/parser/issues/issue-7970b.rs new file mode 100644 index 000000000..1c4abce39 --- /dev/null +++ b/src/test/ui/parser/issues/issue-7970b.rs @@ -0,0 +1,4 @@ +fn main() {} + +macro_rules! test {} +//~^ ERROR unexpected end of macro invocation diff --git a/src/test/ui/parser/issues/issue-7970b.stderr b/src/test/ui/parser/issues/issue-7970b.stderr new file mode 100644 index 000000000..a62226a8a --- /dev/null +++ b/src/test/ui/parser/issues/issue-7970b.stderr @@ -0,0 +1,8 @@ +error: unexpected end of macro invocation + --> $DIR/issue-7970b.rs:3:1 + | +LL | macro_rules! test {} + | ^^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-81806.rs b/src/test/ui/parser/issues/issue-81806.rs new file mode 100644 index 000000000..ca86788df --- /dev/null +++ b/src/test/ui/parser/issues/issue-81806.rs @@ -0,0 +1,5 @@ +trait T { const +impl //~ ERROR: expected identifier, found keyword `impl` +} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-81806.stderr b/src/test/ui/parser/issues/issue-81806.stderr new file mode 100644 index 000000000..40873388d --- /dev/null +++ b/src/test/ui/parser/issues/issue-81806.stderr @@ -0,0 +1,17 @@ +error: expected identifier, found keyword `impl` + --> $DIR/issue-81806.rs:2:1 + | +LL | trait T { const + | - while parsing this item list starting here +LL | impl + | ^^^^ expected identifier, found keyword +LL | } + | - the item list ends here + | +help: escape `impl` to use it as an identifier + | +LL | r#impl + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-83639.rs b/src/test/ui/parser/issues/issue-83639.rs new file mode 100644 index 000000000..6ddbedfa0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-83639.rs @@ -0,0 +1,6 @@ +// check-fail +// ignore-tidy-tab + +fn main() { + """ " //~ ERROR +} diff --git a/src/test/ui/parser/issues/issue-83639.stderr b/src/test/ui/parser/issues/issue-83639.stderr new file mode 100644 index 000000000..4c10df191 --- /dev/null +++ b/src/test/ui/parser/issues/issue-83639.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `" "` + --> $DIR/issue-83639.rs:5:7 + | +LL | """ " + | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-84104.rs b/src/test/ui/parser/issues/issue-84104.rs new file mode 100644 index 000000000..998949b94 --- /dev/null +++ b/src/test/ui/parser/issues/issue-84104.rs @@ -0,0 +1,3 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected one of +#[i=i::<ښܖ< diff --git a/src/test/ui/parser/issues/issue-84104.stderr b/src/test/ui/parser/issues/issue-84104.stderr new file mode 100644 index 000000000..aff31f2c9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-84104.stderr @@ -0,0 +1,16 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-84104.rs:3:13 + | +LL | #[i=i::<ښܖ< + | - ^ + | | + | unclosed delimiter + +error: expected one of `>`, a const expression, lifetime, or type, found `]` + --> $DIR/issue-84104.rs:3:13 + | +LL | #[i=i::<ښܖ< + | ^ expected one of `>`, a const expression, lifetime, or type + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-84117.rs b/src/test/ui/parser/issues/issue-84117.rs new file mode 100644 index 000000000..c9ebf1335 --- /dev/null +++ b/src/test/ui/parser/issues/issue-84117.rs @@ -0,0 +1,9 @@ +fn main() { + let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + //~^ ERROR expected one of `>`, a const expression + //~| ERROR expected one of `>`, a const expression, lifetime, or type, found `}` + //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` + //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` + //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` +} +//~^ ERROR expected one of `,` or `>`, found `}` diff --git a/src/test/ui/parser/issues/issue-84117.stderr b/src/test/ui/parser/issues/issue-84117.stderr new file mode 100644 index 000000000..237bc11bd --- /dev/null +++ b/src/test/ui/parser/issues/issue-84117.stderr @@ -0,0 +1,72 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `}` + --> $DIR/issue-84117.rs:2:67 + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + | ----------- ^ expected one of `>`, a const expression, lifetime, or type + | | + | while parsing the type for `inner_local` + | +help: you might have meant to end the type parameters here + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str>, } + | + +help: use `=` if you meant to assign + | +LL | let outer_local:e_outer<&str, { let inner_local =e_inner<&str, } + | ~ + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` + --> $DIR/issue-84117.rs:2:65 + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + | ^ expected one of 8 possible tokens + +error: expected one of `,` or `>`, found `}` + --> $DIR/issue-84117.rs:8:1 + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + | ----------- while parsing the type for `outer_local` - expected one of `,` or `>` +... +LL | } + | ^ unexpected token + | +help: you might have meant to end the type parameters here + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }> + | + +help: use `=` if you meant to assign + | +LL | let outer_local =e_outer<&str, { let inner_local:e_inner<&str, } + | ~ + +error: expected one of `>`, a const expression, lifetime, or type, found `}` + --> $DIR/issue-84117.rs:2:67 + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + | ----------- ^ expected one of `>`, a const expression, lifetime, or type + | | + | while parsing the type for `inner_local` + | +help: you might have meant to end the type parameters here + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str>, } + | + +help: use `=` if you meant to assign + | +LL | let outer_local:e_outer<&str, { let inner_local =e_inner<&str, } + | ~ + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` + --> $DIR/issue-84117.rs:2:65 + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + | ^ expected one of 8 possible tokens + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` + --> $DIR/issue-84117.rs:2:33 + | +LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } + | ^ expected one of 8 possible tokens + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issues/issue-84148-1.rs b/src/test/ui/parser/issues/issue-84148-1.rs new file mode 100644 index 000000000..9fa8086c2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-84148-1.rs @@ -0,0 +1,3 @@ +fn f(t:for<>t?) +//~^ ERROR: expected one of +//~| ERROR: invalid `?` in type diff --git a/src/test/ui/parser/issues/issue-84148-1.stderr b/src/test/ui/parser/issues/issue-84148-1.stderr new file mode 100644 index 000000000..9261067c2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-84148-1.stderr @@ -0,0 +1,19 @@ +error: invalid `?` in type + --> $DIR/issue-84148-1.rs:1:14 + | +LL | fn f(t:for<>t?) + | ^ `?` is only allowed on expressions, not types + | +help: if you meant to express that the type might not contain a value, use the `Option` wrapper type + | +LL | fn f(t:Option<for<>t>) + | +++++++ ~ + +error: expected one of `->`, `where`, or `{`, found `<eof>` + --> $DIR/issue-84148-1.rs:1:15 + | +LL | fn f(t:for<>t?) + | ^ expected one of `->`, `where`, or `{` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-84148-2.rs b/src/test/ui/parser/issues/issue-84148-2.rs new file mode 100644 index 000000000..2f6a7facf --- /dev/null +++ b/src/test/ui/parser/issues/issue-84148-2.rs @@ -0,0 +1,3 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: invalid `?` in type +fn f(t:for<>t? diff --git a/src/test/ui/parser/issues/issue-84148-2.stderr b/src/test/ui/parser/issues/issue-84148-2.stderr new file mode 100644 index 000000000..71d543f9b --- /dev/null +++ b/src/test/ui/parser/issues/issue-84148-2.stderr @@ -0,0 +1,27 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-84148-2.rs:3:16 + | +LL | fn f(t:for<>t? + | - ^ + | | + | unclosed delimiter + +error: invalid `?` in type + --> $DIR/issue-84148-2.rs:3:14 + | +LL | fn f(t:for<>t? + | ^ `?` is only allowed on expressions, not types + | +help: if you meant to express that the type might not contain a value, use the `Option` wrapper type + | +LL | fn f(t:Option<for<>t> + | +++++++ ~ + +error: expected one of `->`, `where`, or `{`, found `<eof>` + --> $DIR/issue-84148-2.rs:3:16 + | +LL | fn f(t:for<>t? + | ^ expected one of `->`, `where`, or `{` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-8537.rs b/src/test/ui/parser/issues/issue-8537.rs new file mode 100644 index 000000000..9d0cbce6c --- /dev/null +++ b/src/test/ui/parser/issues/issue-8537.rs @@ -0,0 +1,5 @@ +pub extern + "invalid-ab_isize" //~ ERROR invalid ABI +fn foo() {} + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-8537.stderr b/src/test/ui/parser/issues/issue-8537.stderr new file mode 100644 index 000000000..505d830ef --- /dev/null +++ b/src/test/ui/parser/issues/issue-8537.stderr @@ -0,0 +1,11 @@ +error[E0703]: invalid ABI: found `invalid-ab_isize` + --> $DIR/issue-8537.rs:2:3 + | +LL | "invalid-ab_isize" + | ^^^^^^^^^^^^^^^^^^ invalid ABI + | + = help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted, rust-cold + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0703`. diff --git a/src/test/ui/parser/issues/issue-86895.rs b/src/test/ui/parser/issues/issue-86895.rs new file mode 100644 index 000000000..4cd098431 --- /dev/null +++ b/src/test/ui/parser/issues/issue-86895.rs @@ -0,0 +1,3 @@ +const pub () {} +//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe` +pub fn main() {} diff --git a/src/test/ui/parser/issues/issue-86895.stderr b/src/test/ui/parser/issues/issue-86895.stderr new file mode 100644 index 000000000..575d857c0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-86895.stderr @@ -0,0 +1,8 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-86895.rs:1:7 + | +LL | const pub () {} + | ^^^ expected one of `async`, `extern`, `fn`, or `unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-87086-colon-path-sep.rs b/src/test/ui/parser/issues/issue-87086-colon-path-sep.rs new file mode 100644 index 000000000..0b7b67496 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87086-colon-path-sep.rs @@ -0,0 +1,79 @@ +// Tests that a suggestion is issued if the user wrote a colon instead of +// a path separator in a match arm. + +mod qux { + pub enum Foo { + Bar, + Baz, + } +} + +use qux::Foo; + +fn f() -> Foo { Foo::Bar } + +fn g1() { + match f() { + Foo:Bar => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + match f() { + qux::Foo:Bar => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + match f() { + qux:Foo::Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + match f() { + qux: Foo::Baz if true => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + if let Foo:Bar = f() { + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + } +} + +fn g1_neg() { + match f() { + ref qux: Foo::Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } +} + +fn g2_neg() { + match f() { + mut qux: Foo::Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } +} + +fn main() { + let myfoo = Foo::Bar; + match myfoo { + Foo::Bar => {} + Foo:Bar::Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + //~| ERROR: failed to resolve: `Bar` is a variant, not a module + } + match myfoo { + Foo::Bar => {} + Foo:Bar => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + } +} diff --git a/src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr b/src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr new file mode 100644 index 000000000..2050a16be --- /dev/null +++ b/src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr @@ -0,0 +1,90 @@ +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:17:12 + | +LL | Foo:Bar => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `{`, or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:23:17 + | +LL | qux::Foo:Bar => {} + | ^ + | | + | expected one of 8 possible tokens + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:29:12 + | +LL | qux:Foo::Baz => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:35:12 + | +LL | qux: Foo::Baz if true => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:40:15 + | +LL | if let Foo:Bar = f() { + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:48:16 + | +LL | ref qux: Foo::Baz => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:57:16 + | +LL | mut qux: Foo::Baz => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:68:12 + | +LL | Foo:Bar::Baz => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:75:12 + | +LL | Foo:Bar => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error[E0433]: failed to resolve: `Bar` is a variant, not a module + --> $DIR/issue-87086-colon-path-sep.rs:68:13 + | +LL | Foo:Bar::Baz => {} + | ^^^ `Bar` is a variant, not a module + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed b/src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed new file mode 100644 index 000000000..53f071db7 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed @@ -0,0 +1,10 @@ +// run-rustfix +// Parser should know when a semicolon is missing. +// https://github.com/rust-lang/rust/issues/87197 + +fn main() { + let x = 100; //~ ERROR: expected `;` + println!("{}", x); //~ ERROR: expected `;` + let y = 200; //~ ERROR: expected `;` + println!("{}", y); +} diff --git a/src/test/ui/parser/issues/issue-87197-missing-semicolon.rs b/src/test/ui/parser/issues/issue-87197-missing-semicolon.rs new file mode 100644 index 000000000..db0edf452 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87197-missing-semicolon.rs @@ -0,0 +1,10 @@ +// run-rustfix +// Parser should know when a semicolon is missing. +// https://github.com/rust-lang/rust/issues/87197 + +fn main() { + let x = 100 //~ ERROR: expected `;` + println!("{}", x) //~ ERROR: expected `;` + let y = 200 //~ ERROR: expected `;` + println!("{}", y); +} diff --git a/src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr b/src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr new file mode 100644 index 000000000..57772de1e --- /dev/null +++ b/src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr @@ -0,0 +1,26 @@ +error: expected `;`, found `println` + --> $DIR/issue-87197-missing-semicolon.rs:6:16 + | +LL | let x = 100 + | ^ help: add `;` here +LL | println!("{}", x) + | ------- unexpected token + +error: expected `;`, found keyword `let` + --> $DIR/issue-87197-missing-semicolon.rs:7:22 + | +LL | println!("{}", x) + | ^ help: add `;` here +LL | let y = 200 + | --- unexpected token + +error: expected `;`, found `println` + --> $DIR/issue-87197-missing-semicolon.rs:8:16 + | +LL | let y = 200 + | ^ help: add `;` here +LL | println!("{}", y); + | ------- unexpected token + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs new file mode 100644 index 000000000..df0cd5439 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs @@ -0,0 +1,9 @@ +// edition:2018 + +// Test that even when `const` is already present, the proposed fix is to remove the second `const` + +const async const fn test() {} +//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const` +//~| NOTE expected one of `extern`, `fn`, or `unsafe` +//~| HELP `const` already used earlier, remove this one +//~| NOTE `const` first seen here diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr new file mode 100644 index 000000000..977c6ebfe --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr @@ -0,0 +1,17 @@ +error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const` + --> $DIR/const-async-const.rs:5:13 + | +LL | const async const fn test() {} + | ^^^^^ + | | + | expected one of `extern`, `fn`, or `unsafe` + | help: `const` already used earlier, remove this one + | +note: `const` first seen here + --> $DIR/const-async-const.rs:5:1 + | +LL | const async const fn test() {} + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs new file mode 100644 index 000000000..bbebc99e9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs @@ -0,0 +1,14 @@ +// edition:2018 + +// There is an order to respect for keywords before a function: +// `<visibility>, const, async, unsafe, extern, "<ABI>"` +// +// This test ensures the compiler is helpful about them being misplaced. +// Visibilities are tested elsewhere. + +async unsafe const fn test() {} +//~^ ERROR expected one of `extern` or `fn`, found keyword `const` +//~| NOTE expected one of `extern` or `fn` +//~| HELP `const` must come before `async unsafe` +//~| SUGGESTION const async unsafe +//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr new file mode 100644 index 000000000..f455caba1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr @@ -0,0 +1,13 @@ +error: expected one of `extern` or `fn`, found keyword `const` + --> $DIR/several-kw-jump.rs:9:14 + | +LL | async unsafe const fn test() {} + | -------------^^^^^ + | | | + | | expected one of `extern` or `fn` + | help: `const` must come before `async unsafe`: `const async unsafe` + | + = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs new file mode 100644 index 000000000..4ff4cf5c8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs @@ -0,0 +1,14 @@ +// edition:2018 + +// There is an order to respect for keywords before a function: +// `<visibility>, const, async, unsafe, extern, "<ABI>"` +// +// This test ensures the compiler is helpful about them being misplaced. +// Visibilities are tested elsewhere. + +unsafe async fn test() {} +//~^ ERROR expected one of `extern` or `fn`, found keyword `async` +//~| NOTE expected one of `extern` or `fn` +//~| HELP `async` must come before `unsafe` +//~| SUGGESTION async unsafe +//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr new file mode 100644 index 000000000..e9eb14bf0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr @@ -0,0 +1,13 @@ +error: expected one of `extern` or `fn`, found keyword `async` + --> $DIR/wrong-async.rs:9:8 + | +LL | unsafe async fn test() {} + | -------^^^^^ + | | | + | | expected one of `extern` or `fn` + | help: `async` must come before `unsafe`: `async unsafe` + | + = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs new file mode 100644 index 000000000..2f5fbc513 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs @@ -0,0 +1,14 @@ +// edition:2018 + +// There is an order to respect for keywords before a function: +// `<visibility>, const, async, unsafe, extern, "<ABI>"` +// +// This test ensures the compiler is helpful about them being misplaced. +// Visibilities are tested elsewhere. + +unsafe const fn test() {} +//~^ ERROR expected one of `extern` or `fn`, found keyword `const` +//~| NOTE expected one of `extern` or `fn` +//~| HELP `const` must come before `unsafe` +//~| SUGGESTION const unsafe +//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr new file mode 100644 index 000000000..0d2bc3472 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr @@ -0,0 +1,13 @@ +error: expected one of `extern` or `fn`, found keyword `const` + --> $DIR/wrong-const.rs:9:8 + | +LL | unsafe const fn test() {} + | -------^^^^^ + | | | + | | expected one of `extern` or `fn` + | help: `const` must come before `unsafe`: `const unsafe` + | + = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs new file mode 100644 index 000000000..df2412e3e --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs @@ -0,0 +1,14 @@ +// edition:2018 + +// There is an order to respect for keywords before a function: +// `<visibility>, const, async, unsafe, extern, "<ABI>"` +// +// This test ensures the compiler is helpful about them being misplaced. +// Visibilities are tested elsewhere. + +extern unsafe fn test() {} +//~^ ERROR expected `fn`, found keyword `unsafe` +//~| NOTE expected `fn` +//~| HELP `unsafe` must come before `extern` +//~| SUGGESTION unsafe extern +//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr new file mode 100644 index 000000000..4224713cc --- /dev/null +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr @@ -0,0 +1,13 @@ +error: expected `fn`, found keyword `unsafe` + --> $DIR/wrong-unsafe.rs:9:8 + | +LL | extern unsafe fn test() {} + | -------^^^^^^ + | | | + | | expected `fn` + | help: `unsafe` must come before `extern`: `unsafe extern` + | + = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-87635.rs b/src/test/ui/parser/issues/issue-87635.rs new file mode 100644 index 000000000..f70a87fb0 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87635.rs @@ -0,0 +1,9 @@ +struct Foo {} + +impl Foo { + pub fn bar() + //~^ ERROR: associated function in `impl` without body +} +//~^ERROR expected one of `->`, `where`, or `{`, found `}` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-87635.stderr b/src/test/ui/parser/issues/issue-87635.stderr new file mode 100644 index 000000000..1d459f1b9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87635.stderr @@ -0,0 +1,19 @@ +error: expected one of `->`, `where`, or `{`, found `}` + --> $DIR/issue-87635.rs:6:1 + | +LL | pub fn bar() + | --- - expected one of `->`, `where`, or `{` + | | + | while parsing this `fn` +LL | +LL | } + | ^ unexpected token + +error: associated function in `impl` without body + --> $DIR/issue-87635.rs:4:5 + | +LL | pub fn bar() + | ^^^^^^^^^^^^- help: provide a definition for the function: `{ <body> }` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-87812-path.rs b/src/test/ui/parser/issues/issue-87812-path.rs new file mode 100644 index 000000000..b88780876 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87812-path.rs @@ -0,0 +1,11 @@ +macro_rules! foo { + ( $f:path ) => {{ + let _: usize = $f; //~ERROR + }}; +} + +struct Baz; + +fn main() { + foo!(Baz); +} diff --git a/src/test/ui/parser/issues/issue-87812-path.stderr b/src/test/ui/parser/issues/issue-87812-path.stderr new file mode 100644 index 000000000..f8ee05175 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87812-path.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/issue-87812-path.rs:3:24 + | +LL | let _: usize = $f; + | ----- ^^ expected `usize`, found struct `Baz` + | | + | expected due to this +... +LL | foo!(Baz); + | --------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-87812.rs b/src/test/ui/parser/issues/issue-87812.rs new file mode 100644 index 000000000..0ba87b995 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87812.rs @@ -0,0 +1,13 @@ +#![deny(break_with_label_and_loop)] + +macro_rules! foo { + ( $f:block ) => { + '_l: loop { + break '_l $f; //~ERROR + } + }; +} + +fn main() { + let x = foo!({ 3 }); +} diff --git a/src/test/ui/parser/issues/issue-87812.stderr b/src/test/ui/parser/issues/issue-87812.stderr new file mode 100644 index 000000000..d61ee23a5 --- /dev/null +++ b/src/test/ui/parser/issues/issue-87812.stderr @@ -0,0 +1,22 @@ +error: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression + --> $DIR/issue-87812.rs:6:13 + | +LL | break '_l $f; + | ^^^^^^^^^^^^ +... +LL | let x = foo!({ 3 }); + | ----------- in this macro invocation + | +note: the lint level is defined here + --> $DIR/issue-87812.rs:1:9 + | +LL | #![deny(break_with_label_and_loop)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: wrap this expression in parentheses + | +LL | break '_l ($f); + | + + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-88276-unary-plus.fixed b/src/test/ui/parser/issues/issue-88276-unary-plus.fixed new file mode 100644 index 000000000..25b7c340f --- /dev/null +++ b/src/test/ui/parser/issues/issue-88276-unary-plus.fixed @@ -0,0 +1,8 @@ +// run-rustfix +#[allow(unused_parens)] +fn main() { + let _ = 1; //~ ERROR leading `+` is not supported + let _ = (1.0 + 2.0) * 3.0; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported + let _ = [3, 4+6]; //~ ERROR leading `+` is not supported +} diff --git a/src/test/ui/parser/issues/issue-88276-unary-plus.rs b/src/test/ui/parser/issues/issue-88276-unary-plus.rs new file mode 100644 index 000000000..11b2e9d60 --- /dev/null +++ b/src/test/ui/parser/issues/issue-88276-unary-plus.rs @@ -0,0 +1,8 @@ +// run-rustfix +#[allow(unused_parens)] +fn main() { + let _ = +1; //~ ERROR leading `+` is not supported + let _ = (1.0 + +2.0) * +3.0; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported + let _ = [+3, 4+6]; //~ ERROR leading `+` is not supported +} diff --git a/src/test/ui/parser/issues/issue-88276-unary-plus.stderr b/src/test/ui/parser/issues/issue-88276-unary-plus.stderr new file mode 100644 index 000000000..363e08201 --- /dev/null +++ b/src/test/ui/parser/issues/issue-88276-unary-plus.stderr @@ -0,0 +1,50 @@ +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:4:13 + | +LL | let _ = +1; + | ^ unexpected `+` + | +help: try removing the `+` + | +LL - let _ = +1; +LL + let _ = 1; + | + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:5:20 + | +LL | let _ = (1.0 + +2.0) * +3.0; + | ^ unexpected `+` + | +help: try removing the `+` + | +LL - let _ = (1.0 + +2.0) * +3.0; +LL + let _ = (1.0 + 2.0) * +3.0; + | + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:5:28 + | +LL | let _ = (1.0 + +2.0) * +3.0; + | ^ unexpected `+` + | +help: try removing the `+` + | +LL - let _ = (1.0 + +2.0) * +3.0; +LL + let _ = (1.0 + +2.0) * 3.0; + | + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:7:14 + | +LL | let _ = [+3, 4+6]; + | ^ unexpected `+` + | +help: try removing the `+` + | +LL - let _ = [+3, 4+6]; +LL + let _ = [3, 4+6]; + | + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/issues/issue-88583-union-as-ident.rs b/src/test/ui/parser/issues/issue-88583-union-as-ident.rs new file mode 100644 index 000000000..b3d66d46b --- /dev/null +++ b/src/test/ui/parser/issues/issue-88583-union-as-ident.rs @@ -0,0 +1,15 @@ +// check-pass + +#![allow(non_camel_case_types)] + +struct union; + +impl union { + pub fn new() -> Self { + union { } + } +} + +fn main() { + let _u = union::new(); +} diff --git a/src/test/ui/parser/issues/issue-88770.rs b/src/test/ui/parser/issues/issue-88770.rs new file mode 100644 index 000000000..bb69951c7 --- /dev/null +++ b/src/test/ui/parser/issues/issue-88770.rs @@ -0,0 +1,11 @@ +// Regression test for the ICE described in #88770. + +// error-pattern:this file contains an unclosed delimiter +// error-pattern:expected one of +// error-pattern:missing `in` in `for` loop +// error-pattern:expected one of `!`, `)`, `,`, `.`, `::`, `;`, `?`, `{`, or an operator, found `e` + +fn m(){print!("",(c for&g +u +e +e diff --git a/src/test/ui/parser/issues/issue-88770.stderr b/src/test/ui/parser/issues/issue-88770.stderr new file mode 100644 index 000000000..4e3a21613 --- /dev/null +++ b/src/test/ui/parser/issues/issue-88770.stderr @@ -0,0 +1,60 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-88770.rs:11:3 + | +LL | fn m(){print!("",(c for&g + | - - - unclosed delimiter + | | | + | | unclosed delimiter + | unclosed delimiter +... +LL | e + | ^ + +error: this file contains an unclosed delimiter + --> $DIR/issue-88770.rs:11:3 + | +LL | fn m(){print!("",(c for&g + | - - - unclosed delimiter + | | | + | | unclosed delimiter + | unclosed delimiter +... +LL | e + | ^ + +error: this file contains an unclosed delimiter + --> $DIR/issue-88770.rs:11:3 + | +LL | fn m(){print!("",(c for&g + | - - - unclosed delimiter + | | | + | | unclosed delimiter + | unclosed delimiter +... +LL | e + | ^ + +error: missing `in` in `for` loop + --> $DIR/issue-88770.rs:8:26 + | +LL | fn m(){print!("",(c for&g + | __________________________^ +LL | | u + | |_ help: try adding `in` here + +error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found keyword `for` + --> $DIR/issue-88770.rs:8:21 + | +LL | fn m(){print!("",(c for&g + | ^^^ expected one of 8 possible tokens + +error: expected one of `!`, `)`, `,`, `.`, `::`, `;`, `?`, `{`, or an operator, found `e` + --> $DIR/issue-88770.rs:11:1 + | +LL | e + | - expected one of 9 possible tokens +LL | e + | ^ unexpected token + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issues/issue-88818.rs b/src/test/ui/parser/issues/issue-88818.rs new file mode 100644 index 000000000..b9233ca83 --- /dev/null +++ b/src/test/ui/parser/issues/issue-88818.rs @@ -0,0 +1,10 @@ +// Regression test for #88818 (improve error message for missing trait +// in `impl for X`). + +struct S { } +impl for S { } +//~^ ERROR: missing trait in a trait impl +//~| HELP: add a trait here +//~| HELP: for an inherent impl, drop this `for` + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-88818.stderr b/src/test/ui/parser/issues/issue-88818.stderr new file mode 100644 index 000000000..6e624c5a2 --- /dev/null +++ b/src/test/ui/parser/issues/issue-88818.stderr @@ -0,0 +1,18 @@ +error: missing trait in a trait impl + --> $DIR/issue-88818.rs:5:5 + | +LL | impl for S { } + | ^ + | +help: add a trait here + | +LL | impl Trait for S { } + | +++++ +help: for an inherent impl, drop this `for` + | +LL - impl for S { } +LL + impl S { } + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-89388.rs b/src/test/ui/parser/issues/issue-89388.rs new file mode 100644 index 000000000..9153c071e --- /dev/null +++ b/src/test/ui/parser/issues/issue-89388.rs @@ -0,0 +1,7 @@ +// Regression test for #89388. + +fn main() { + let option: Option<&[u8]> = Some(b"..."); + let _ = option.map([_]::to_vec); + //~^ ERROR: missing angle brackets in associated item path +} diff --git a/src/test/ui/parser/issues/issue-89388.stderr b/src/test/ui/parser/issues/issue-89388.stderr new file mode 100644 index 000000000..cf28bef0f --- /dev/null +++ b/src/test/ui/parser/issues/issue-89388.stderr @@ -0,0 +1,8 @@ +error: missing angle brackets in associated item path + --> $DIR/issue-89388.rs:5:24 + | +LL | let _ = option.map([_]::to_vec); + | ^^^^^^^^^^^ help: try: `<[_]>::to_vec` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-89396.fixed b/src/test/ui/parser/issues/issue-89396.fixed new file mode 100644 index 000000000..823ad8cd1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-89396.fixed @@ -0,0 +1,16 @@ +// Regression test for issue #89396: Try to recover from a +// `=>` -> `=` or `->` typo in a match arm. + +// run-rustfix + +fn main() { + let opt = Some(42); + let _ = match opt { + Some(_) => true, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + None => false, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + }; +} diff --git a/src/test/ui/parser/issues/issue-89396.rs b/src/test/ui/parser/issues/issue-89396.rs new file mode 100644 index 000000000..f1d9efa52 --- /dev/null +++ b/src/test/ui/parser/issues/issue-89396.rs @@ -0,0 +1,16 @@ +// Regression test for issue #89396: Try to recover from a +// `=>` -> `=` or `->` typo in a match arm. + +// run-rustfix + +fn main() { + let opt = Some(42); + let _ = match opt { + Some(_) = true, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + None -> false, + //~^ ERROR: expected one of + //~| HELP: try using a fat arrow here + }; +} diff --git a/src/test/ui/parser/issues/issue-89396.stderr b/src/test/ui/parser/issues/issue-89396.stderr new file mode 100644 index 000000000..504420574 --- /dev/null +++ b/src/test/ui/parser/issues/issue-89396.stderr @@ -0,0 +1,20 @@ +error: expected one of `=>`, `if`, or `|`, found `=` + --> $DIR/issue-89396.rs:9:17 + | +LL | Some(_) = true, + | ^ + | | + | expected one of `=>`, `if`, or `|` + | help: try using a fat arrow here: `=>` + +error: expected one of `=>`, `@`, `if`, or `|`, found `->` + --> $DIR/issue-89396.rs:12:14 + | +LL | None -> false, + | ^^ + | | + | expected one of `=>`, `@`, `if`, or `|` + | help: try using a fat arrow here: `=>` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issues/issue-89574.rs b/src/test/ui/parser/issues/issue-89574.rs new file mode 100644 index 000000000..0a477f1aa --- /dev/null +++ b/src/test/ui/parser/issues/issue-89574.rs @@ -0,0 +1,4 @@ +fn main() { + const EMPTY_ARRAY = []; + //~^ missing type for `const` item +} diff --git a/src/test/ui/parser/issues/issue-89574.stderr b/src/test/ui/parser/issues/issue-89574.stderr new file mode 100644 index 000000000..cbee3d351 --- /dev/null +++ b/src/test/ui/parser/issues/issue-89574.stderr @@ -0,0 +1,8 @@ +error: missing type for `const` item + --> $DIR/issue-89574.rs:2:11 + | +LL | const EMPTY_ARRAY = []; + | ^^^^^^^^^^^ help: provide a type for the item: `EMPTY_ARRAY: <type>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs new file mode 100644 index 000000000..fe67d9822 --- /dev/null +++ b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs @@ -0,0 +1,15 @@ +// aux-build:issue-89971-outer-attr-following-inner-attr-ice.rs + +#[macro_use] +extern crate issue_89971_outer_attr_following_inner_attr_ice; + +fn main() { + Mew(); + X {}; +} + +#![deny(missing_docs)] +//~^ ERROR an inner attribute is not permitted in this context +#[derive(ICE)] +#[deny(missing_docs)] +struct Mew(); diff --git a/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr new file mode 100644 index 000000000..a5ee24445 --- /dev/null +++ b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr @@ -0,0 +1,18 @@ +error: an inner attribute is not permitted in this context + --> $DIR/issue-89971-outer-attr-following-inner-attr-ice.rs:11:1 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | struct Mew(); + | ------------- the inner attribute doesn't annotate this struct + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the struct, change the attribute from inner to outer style + | +LL - #![deny(missing_docs)] +LL + #[deny(missing_docs)] + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-90993.rs b/src/test/ui/parser/issues/issue-90993.rs new file mode 100644 index 000000000..40e6fc748 --- /dev/null +++ b/src/test/ui/parser/issues/issue-90993.rs @@ -0,0 +1,6 @@ +fn main() { + ...=. + //~^ ERROR: unexpected token: `...` + //~| ERROR: unexpected `=` after inclusive range + //~| ERROR: expected one of `-`, `;`, `}`, or path, found `.` +} diff --git a/src/test/ui/parser/issues/issue-90993.stderr b/src/test/ui/parser/issues/issue-90993.stderr new file mode 100644 index 000000000..ab6bce410 --- /dev/null +++ b/src/test/ui/parser/issues/issue-90993.stderr @@ -0,0 +1,31 @@ +error: unexpected token: `...` + --> $DIR/issue-90993.rs:2:5 + | +LL | ...=. + | ^^^ + | +help: use `..` for an exclusive range + | +LL | ..=. + | ~~ +help: or `..=` for an inclusive range + | +LL | ..==. + | ~~~ + +error: unexpected `=` after inclusive range + --> $DIR/issue-90993.rs:2:5 + | +LL | ...=. + | ^^^^ help: use `..=` instead + | + = note: inclusive ranges end with a single equals sign (`..=`) + +error: expected one of `-`, `;`, `}`, or path, found `.` + --> $DIR/issue-90993.rs:2:9 + | +LL | ...=. + | ^ expected one of `-`, `;`, `}`, or path + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-91461.rs b/src/test/ui/parser/issues/issue-91461.rs new file mode 100644 index 000000000..3e3c411c4 --- /dev/null +++ b/src/test/ui/parser/issues/issue-91461.rs @@ -0,0 +1,6 @@ +fn main() { + a(_:b:,) + //~^ ERROR: expected identifier, found reserved identifier `_` + //~| ERROR: expected type, found `,` + //~| ERROR: expected type, found `,` +} diff --git a/src/test/ui/parser/issues/issue-91461.stderr b/src/test/ui/parser/issues/issue-91461.stderr new file mode 100644 index 000000000..94fcf1721 --- /dev/null +++ b/src/test/ui/parser/issues/issue-91461.stderr @@ -0,0 +1,31 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-91461.rs:2:7 + | +LL | a(_:b:,) + | ^ expected identifier, found reserved identifier + +error: expected type, found `,` + --> $DIR/issue-91461.rs:2:11 + | +LL | a(_:b:,) + | - -^ expected type + | | | + | | tried to parse a type due to this type ascription + | while parsing this struct + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + +error: expected type, found `,` + --> $DIR/issue-91461.rs:2:11 + | +LL | a(_:b:,) + | -^ expected type + | | + | tried to parse a type due to this type ascription + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-93282.rs b/src/test/ui/parser/issues/issue-93282.rs new file mode 100644 index 000000000..261fcb5f9 --- /dev/null +++ b/src/test/ui/parser/issues/issue-93282.rs @@ -0,0 +1,15 @@ +fn main() { + f<'a,> + //~^ ERROR expected + //~| ERROR expected +} + +fn bar(a: usize, b: usize) -> usize { + a + b +} + +fn foo() { + let x = 1; + bar('y, x); + //~^ ERROR expected +} diff --git a/src/test/ui/parser/issues/issue-93282.stderr b/src/test/ui/parser/issues/issue-93282.stderr new file mode 100644 index 000000000..ee554784b --- /dev/null +++ b/src/test/ui/parser/issues/issue-93282.stderr @@ -0,0 +1,25 @@ +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/issue-93282.rs:2:9 + | +LL | f<'a,> + | ^ expected `while`, `for`, `loop` or `{` after a label + +error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `}`, or an operator, found `,` + --> $DIR/issue-93282.rs:2:9 + | +LL | f<'a,> + | ^ expected one of 9 possible tokens + | +help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + | +LL | f::<'a,> + | ++ + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/issue-93282.rs:13:11 + | +LL | bar('y, x); + | ^ expected `while`, `for`, `loop` or `{` after a label + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/issues/issue-93867.rs b/src/test/ui/parser/issues/issue-93867.rs new file mode 100644 index 000000000..507447923 --- /dev/null +++ b/src/test/ui/parser/issues/issue-93867.rs @@ -0,0 +1,10 @@ +pub struct Entry<'a, K, V> { + k: &'a mut K, + v: V, +} + +pub fn entry<'a, K, V>() -> Entry<'a K, V> { +// ^ missing comma +//~^^ expected one of `,` or `>`, found `K` + unimplemented!() +} diff --git a/src/test/ui/parser/issues/issue-93867.stderr b/src/test/ui/parser/issues/issue-93867.stderr new file mode 100644 index 000000000..ee0cb4efd --- /dev/null +++ b/src/test/ui/parser/issues/issue-93867.stderr @@ -0,0 +1,13 @@ +error: expected one of `,` or `>`, found `K` + --> $DIR/issue-93867.rs:6:38 + | +LL | pub fn entry<'a, K, V>() -> Entry<'a K, V> { + | ^ expected one of `,` or `>` + | +help: you might have meant to end the type parameters here + | +LL | pub fn entry<'a, K, V>() -> Entry<'a> K, V> { + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-94340.rs b/src/test/ui/parser/issues/issue-94340.rs new file mode 100644 index 000000000..d0fb84a68 --- /dev/null +++ b/src/test/ui/parser/issues/issue-94340.rs @@ -0,0 +1,8 @@ +// Make sure that unexpected inner attributes are not labeled as outer ones in diagnostics when +// trying to parse an item and that they are subsequently ignored not triggering confusing extra +// diagnostics like "expected item after attributes" which is not true for `include!` which can +// include empty files. + +include!("auxiliary/issue-94340-inc.rs"); + +fn main() {} diff --git a/src/test/ui/parser/issues/issue-94340.stderr b/src/test/ui/parser/issues/issue-94340.stderr new file mode 100644 index 000000000..9fd7c38a8 --- /dev/null +++ b/src/test/ui/parser/issues/issue-94340.stderr @@ -0,0 +1,20 @@ +error: an inner attribute is not permitted in this context + --> $DIR/auxiliary/issue-94340-inc.rs:2:1 + | +LL | #![deny(rust_2018_idioms)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/auxiliary/issue-94340-inc.rs:3:1 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/item-free-const-no-body-semantic-fail.rs b/src/test/ui/parser/item-free-const-no-body-semantic-fail.rs new file mode 100644 index 000000000..613b3c985 --- /dev/null +++ b/src/test/ui/parser/item-free-const-no-body-semantic-fail.rs @@ -0,0 +1,7 @@ +// Semantically, a free `const` item cannot omit its body. + +fn main() {} + +const A: u8; //~ ERROR free constant item without body +const B; //~ ERROR free constant item without body +//~^ ERROR missing type for `const` item diff --git a/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr b/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr new file mode 100644 index 000000000..c340e958e --- /dev/null +++ b/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr @@ -0,0 +1,24 @@ +error: free constant item without body + --> $DIR/item-free-const-no-body-semantic-fail.rs:5:1 + | +LL | const A: u8; + | ^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error: free constant item without body + --> $DIR/item-free-const-no-body-semantic-fail.rs:6:1 + | +LL | const B; + | ^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error: missing type for `const` item + --> $DIR/item-free-const-no-body-semantic-fail.rs:6:7 + | +LL | const B; + | ^ help: provide a type for the item: `B: <type>` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs b/src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs new file mode 100644 index 000000000..acfdd3c36 --- /dev/null +++ b/src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs @@ -0,0 +1,8 @@ +// Syntactically, a free `const` item can omit its body. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +const X: u8; diff --git a/src/test/ui/parser/item-free-static-no-body-semantic-fail.rs b/src/test/ui/parser/item-free-static-no-body-semantic-fail.rs new file mode 100644 index 000000000..780479e3d --- /dev/null +++ b/src/test/ui/parser/item-free-static-no-body-semantic-fail.rs @@ -0,0 +1,11 @@ +// Semantically, a free `static` item cannot omit its body. + +fn main() {} + +static A: u8; //~ ERROR free static item without body +static B; //~ ERROR free static item without body +//~^ ERROR missing type for `static` item + +static mut C: u8; //~ ERROR free static item without body +static mut D; //~ ERROR free static item without body +//~^ ERROR missing type for `static mut` item diff --git a/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr b/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr new file mode 100644 index 000000000..4d542b798 --- /dev/null +++ b/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr @@ -0,0 +1,46 @@ +error: free static item without body + --> $DIR/item-free-static-no-body-semantic-fail.rs:5:1 + | +LL | static A: u8; + | ^^^^^^^^^^^^- + | | + | help: provide a definition for the static: `= <expr>;` + +error: free static item without body + --> $DIR/item-free-static-no-body-semantic-fail.rs:6:1 + | +LL | static B; + | ^^^^^^^^- + | | + | help: provide a definition for the static: `= <expr>;` + +error: free static item without body + --> $DIR/item-free-static-no-body-semantic-fail.rs:9:1 + | +LL | static mut C: u8; + | ^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the static: `= <expr>;` + +error: free static item without body + --> $DIR/item-free-static-no-body-semantic-fail.rs:10:1 + | +LL | static mut D; + | ^^^^^^^^^^^^- + | | + | help: provide a definition for the static: `= <expr>;` + +error: missing type for `static` item + --> $DIR/item-free-static-no-body-semantic-fail.rs:6:8 + | +LL | static B; + | ^ help: provide a type for the item: `B: <type>` + +error: missing type for `static mut` item + --> $DIR/item-free-static-no-body-semantic-fail.rs:10:12 + | +LL | static mut D; + | ^ help: provide a type for the item: `D: <type>` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs b/src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs new file mode 100644 index 000000000..db0039204 --- /dev/null +++ b/src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs @@ -0,0 +1,8 @@ +// Syntactically, a free `const` item can omit its body. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +static X: u8; diff --git a/src/test/ui/parser/item-free-type-bounds-semantic-fail.rs b/src/test/ui/parser/item-free-type-bounds-semantic-fail.rs new file mode 100644 index 000000000..9db4111fb --- /dev/null +++ b/src/test/ui/parser/item-free-type-bounds-semantic-fail.rs @@ -0,0 +1,20 @@ +fn main() {} + +fn semantics() { + type A: Ord; + //~^ ERROR bounds on `type`s in this context have no effect + //~| ERROR free type alias without body + type B: Ord = u8; + //~^ ERROR bounds on `type`s in this context have no effect + type C: Ord where 'static: 'static = u8; + //~^ ERROR bounds on `type`s in this context have no effect + type D<_T>: Ord; + //~^ ERROR bounds on `type`s in this context have no effect + //~| ERROR free type alias without body + type E<_T>: Ord = u8; + //~^ ERROR bounds on `type`s in this context have no effect + //~| ERROR type parameter `_T` is unused + type F<_T>: Ord where 'static: 'static = u8; + //~^ ERROR bounds on `type`s in this context have no effect + //~| ERROR type parameter `_T` is unused +} diff --git a/src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr b/src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr new file mode 100644 index 000000000..1b0865128 --- /dev/null +++ b/src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr @@ -0,0 +1,67 @@ +error: free type alias without body + --> $DIR/item-free-type-bounds-semantic-fail.rs:4:5 + | +LL | type A: Ord; + | ^^^^^^^^^^^- + | | + | help: provide a definition for the type: `= <type>;` + +error: bounds on `type`s in this context have no effect + --> $DIR/item-free-type-bounds-semantic-fail.rs:4:13 + | +LL | type A: Ord; + | ^^^ + +error: bounds on `type`s in this context have no effect + --> $DIR/item-free-type-bounds-semantic-fail.rs:7:13 + | +LL | type B: Ord = u8; + | ^^^ + +error: bounds on `type`s in this context have no effect + --> $DIR/item-free-type-bounds-semantic-fail.rs:9:13 + | +LL | type C: Ord where 'static: 'static = u8; + | ^^^ + +error: free type alias without body + --> $DIR/item-free-type-bounds-semantic-fail.rs:11:5 + | +LL | type D<_T>: Ord; + | ^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the type: `= <type>;` + +error: bounds on `type`s in this context have no effect + --> $DIR/item-free-type-bounds-semantic-fail.rs:11:17 + | +LL | type D<_T>: Ord; + | ^^^ + +error: bounds on `type`s in this context have no effect + --> $DIR/item-free-type-bounds-semantic-fail.rs:14:17 + | +LL | type E<_T>: Ord = u8; + | ^^^ + +error: bounds on `type`s in this context have no effect + --> $DIR/item-free-type-bounds-semantic-fail.rs:17:17 + | +LL | type F<_T>: Ord where 'static: 'static = u8; + | ^^^ + +error[E0091]: type parameter `_T` is unused + --> $DIR/item-free-type-bounds-semantic-fail.rs:14:12 + | +LL | type E<_T>: Ord = u8; + | ^^ unused type parameter + +error[E0091]: type parameter `_T` is unused + --> $DIR/item-free-type-bounds-semantic-fail.rs:17:12 + | +LL | type F<_T>: Ord where 'static: 'static = u8; + | ^^ unused type parameter + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0091`. diff --git a/src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs b/src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs new file mode 100644 index 000000000..58fc926d0 --- /dev/null +++ b/src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs @@ -0,0 +1,13 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + type A: Ord; + type B: Ord = u8; + type C: Ord where 'static: 'static = u8; + type D<_T>: Ord; + type E<_T>: Ord = u8; + type F<_T>: Ord where 'static: 'static = u8; +} diff --git a/src/test/ui/parser/keyword-abstract.rs b/src/test/ui/parser/keyword-abstract.rs new file mode 100644 index 000000000..570206575 --- /dev/null +++ b/src/test/ui/parser/keyword-abstract.rs @@ -0,0 +1,3 @@ +fn main() { + let abstract = (); //~ ERROR expected identifier, found reserved keyword `abstract` +} diff --git a/src/test/ui/parser/keyword-abstract.stderr b/src/test/ui/parser/keyword-abstract.stderr new file mode 100644 index 000000000..b7d1ce7cd --- /dev/null +++ b/src/test/ui/parser/keyword-abstract.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `abstract` + --> $DIR/keyword-abstract.rs:2:9 + | +LL | let abstract = (); + | ^^^^^^^^ expected identifier, found reserved keyword + | +help: escape `abstract` to use it as an identifier + | +LL | let r#abstract = (); + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-as-as-identifier.rs b/src/test/ui/parser/keyword-as-as-identifier.rs new file mode 100644 index 000000000..cd47c8a39 --- /dev/null +++ b/src/test/ui/parser/keyword-as-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py as' + +fn main() { + let as = "foo"; //~ error: expected identifier, found keyword `as` +} diff --git a/src/test/ui/parser/keyword-as-as-identifier.stderr b/src/test/ui/parser/keyword-as-as-identifier.stderr new file mode 100644 index 000000000..3c5ad950d --- /dev/null +++ b/src/test/ui/parser/keyword-as-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `as` + --> $DIR/keyword-as-as-identifier.rs:4:9 + | +LL | let as = "foo"; + | ^^ expected identifier, found keyword + | +help: escape `as` to use it as an identifier + | +LL | let r#as = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-box-as-identifier.rs b/src/test/ui/parser/keyword-box-as-identifier.rs new file mode 100644 index 000000000..2cf49b66b --- /dev/null +++ b/src/test/ui/parser/keyword-box-as-identifier.rs @@ -0,0 +1,10 @@ +fn main() { + let box = 0; + //~^ ERROR expected pattern, found `=` + let box: bool; + //~^ ERROR expected pattern, found `:` + let mut box = 0; + //~^ ERROR expected pattern, found `=` + let (box,) = (0,); + //~^ ERROR expected pattern, found `,` +} diff --git a/src/test/ui/parser/keyword-box-as-identifier.stderr b/src/test/ui/parser/keyword-box-as-identifier.stderr new file mode 100644 index 000000000..eaa1f8003 --- /dev/null +++ b/src/test/ui/parser/keyword-box-as-identifier.stderr @@ -0,0 +1,66 @@ +error: expected pattern, found `=` + --> $DIR/keyword-box-as-identifier.rs:2:13 + | +LL | let box = 0; + | ^ + | +note: `box` is a reserved keyword + --> $DIR/keyword-box-as-identifier.rs:2:9 + | +LL | let box = 0; + | ^^^ +help: escape `box` to use it as an identifier + | +LL | let r#box = 0; + | ++ + +error: expected pattern, found `:` + --> $DIR/keyword-box-as-identifier.rs:4:12 + | +LL | let box: bool; + | ^ + | +note: `box` is a reserved keyword + --> $DIR/keyword-box-as-identifier.rs:4:9 + | +LL | let box: bool; + | ^^^ +help: escape `box` to use it as an identifier + | +LL | let r#box: bool; + | ++ + +error: expected pattern, found `=` + --> $DIR/keyword-box-as-identifier.rs:6:17 + | +LL | let mut box = 0; + | ^ + | +note: `box` is a reserved keyword + --> $DIR/keyword-box-as-identifier.rs:6:13 + | +LL | let mut box = 0; + | ^^^ +help: escape `box` to use it as an identifier + | +LL | let mut r#box = 0; + | ++ + +error: expected pattern, found `,` + --> $DIR/keyword-box-as-identifier.rs:8:13 + | +LL | let (box,) = (0,); + | ^ + | +note: `box` is a reserved keyword + --> $DIR/keyword-box-as-identifier.rs:8:10 + | +LL | let (box,) = (0,); + | ^^^ +help: escape `box` to use it as an identifier + | +LL | let (r#box,) = (0,); + | ++ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/keyword-break-as-identifier.rs b/src/test/ui/parser/keyword-break-as-identifier.rs new file mode 100644 index 000000000..04b25a7aa --- /dev/null +++ b/src/test/ui/parser/keyword-break-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py break' + +fn main() { + let break = "foo"; //~ error: expected identifier, found keyword `break` +} diff --git a/src/test/ui/parser/keyword-break-as-identifier.stderr b/src/test/ui/parser/keyword-break-as-identifier.stderr new file mode 100644 index 000000000..a4535eb40 --- /dev/null +++ b/src/test/ui/parser/keyword-break-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `break` + --> $DIR/keyword-break-as-identifier.rs:4:9 + | +LL | let break = "foo"; + | ^^^^^ expected identifier, found keyword + | +help: escape `break` to use it as an identifier + | +LL | let r#break = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-const-as-identifier.rs b/src/test/ui/parser/keyword-const-as-identifier.rs new file mode 100644 index 000000000..6a2d926bf --- /dev/null +++ b/src/test/ui/parser/keyword-const-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py const' + +fn main() { + let const = "foo"; //~ error: expected identifier, found keyword `const` +} diff --git a/src/test/ui/parser/keyword-const-as-identifier.stderr b/src/test/ui/parser/keyword-const-as-identifier.stderr new file mode 100644 index 000000000..31922f150 --- /dev/null +++ b/src/test/ui/parser/keyword-const-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `const` + --> $DIR/keyword-const-as-identifier.rs:4:9 + | +LL | let const = "foo"; + | ^^^^^ expected identifier, found keyword + | +help: escape `const` to use it as an identifier + | +LL | let r#const = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-continue-as-identifier.rs b/src/test/ui/parser/keyword-continue-as-identifier.rs new file mode 100644 index 000000000..cfdd62a2d --- /dev/null +++ b/src/test/ui/parser/keyword-continue-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py continue' + +fn main() { + let continue = "foo"; //~ error: expected identifier, found keyword `continue` +} diff --git a/src/test/ui/parser/keyword-continue-as-identifier.stderr b/src/test/ui/parser/keyword-continue-as-identifier.stderr new file mode 100644 index 000000000..81285633f --- /dev/null +++ b/src/test/ui/parser/keyword-continue-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `continue` + --> $DIR/keyword-continue-as-identifier.rs:4:9 + | +LL | let continue = "foo"; + | ^^^^^^^^ expected identifier, found keyword + | +help: escape `continue` to use it as an identifier + | +LL | let r#continue = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-else-as-identifier.rs b/src/test/ui/parser/keyword-else-as-identifier.rs new file mode 100644 index 000000000..f12dac3ff --- /dev/null +++ b/src/test/ui/parser/keyword-else-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py else' + +fn main() { + let else = "foo"; //~ error: expected identifier, found keyword `else` +} diff --git a/src/test/ui/parser/keyword-else-as-identifier.stderr b/src/test/ui/parser/keyword-else-as-identifier.stderr new file mode 100644 index 000000000..2125fe84a --- /dev/null +++ b/src/test/ui/parser/keyword-else-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `else` + --> $DIR/keyword-else-as-identifier.rs:4:9 + | +LL | let else = "foo"; + | ^^^^ expected identifier, found keyword + | +help: escape `else` to use it as an identifier + | +LL | let r#else = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-enum-as-identifier.rs b/src/test/ui/parser/keyword-enum-as-identifier.rs new file mode 100644 index 000000000..fe66230d0 --- /dev/null +++ b/src/test/ui/parser/keyword-enum-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum' + +fn main() { + let enum = "foo"; //~ error: expected identifier, found keyword `enum` +} diff --git a/src/test/ui/parser/keyword-enum-as-identifier.stderr b/src/test/ui/parser/keyword-enum-as-identifier.stderr new file mode 100644 index 000000000..92d092ccb --- /dev/null +++ b/src/test/ui/parser/keyword-enum-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `enum` + --> $DIR/keyword-enum-as-identifier.rs:4:9 + | +LL | let enum = "foo"; + | ^^^^ expected identifier, found keyword + | +help: escape `enum` to use it as an identifier + | +LL | let r#enum = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-final.rs b/src/test/ui/parser/keyword-final.rs new file mode 100644 index 000000000..a79a11032 --- /dev/null +++ b/src/test/ui/parser/keyword-final.rs @@ -0,0 +1,3 @@ +fn main() { + let final = (); //~ ERROR expected identifier, found reserved keyword `final` +} diff --git a/src/test/ui/parser/keyword-final.stderr b/src/test/ui/parser/keyword-final.stderr new file mode 100644 index 000000000..f1f9f2e2c --- /dev/null +++ b/src/test/ui/parser/keyword-final.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `final` + --> $DIR/keyword-final.rs:2:9 + | +LL | let final = (); + | ^^^^^ expected identifier, found reserved keyword + | +help: escape `final` to use it as an identifier + | +LL | let r#final = (); + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-fn-as-identifier.rs b/src/test/ui/parser/keyword-fn-as-identifier.rs new file mode 100644 index 000000000..f30e115f7 --- /dev/null +++ b/src/test/ui/parser/keyword-fn-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn' + +fn main() { + let fn = "foo"; //~ error: expected identifier, found keyword `fn` +} diff --git a/src/test/ui/parser/keyword-fn-as-identifier.stderr b/src/test/ui/parser/keyword-fn-as-identifier.stderr new file mode 100644 index 000000000..645efbcae --- /dev/null +++ b/src/test/ui/parser/keyword-fn-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `fn` + --> $DIR/keyword-fn-as-identifier.rs:4:9 + | +LL | let fn = "foo"; + | ^^ expected identifier, found keyword + | +help: escape `fn` to use it as an identifier + | +LL | let r#fn = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-for-as-identifier.rs b/src/test/ui/parser/keyword-for-as-identifier.rs new file mode 100644 index 000000000..9e8a2ad53 --- /dev/null +++ b/src/test/ui/parser/keyword-for-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py for' + +fn main() { + let for = "foo"; //~ error: expected identifier, found keyword `for` +} diff --git a/src/test/ui/parser/keyword-for-as-identifier.stderr b/src/test/ui/parser/keyword-for-as-identifier.stderr new file mode 100644 index 000000000..26407cc4d --- /dev/null +++ b/src/test/ui/parser/keyword-for-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `for` + --> $DIR/keyword-for-as-identifier.rs:4:9 + | +LL | let for = "foo"; + | ^^^ expected identifier, found keyword + | +help: escape `for` to use it as an identifier + | +LL | let r#for = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-if-as-identifier.rs b/src/test/ui/parser/keyword-if-as-identifier.rs new file mode 100644 index 000000000..0bd5756af --- /dev/null +++ b/src/test/ui/parser/keyword-if-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py if' + +fn main() { + let if = "foo"; //~ error: expected identifier, found keyword `if` +} diff --git a/src/test/ui/parser/keyword-if-as-identifier.stderr b/src/test/ui/parser/keyword-if-as-identifier.stderr new file mode 100644 index 000000000..26f9a15a7 --- /dev/null +++ b/src/test/ui/parser/keyword-if-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `if` + --> $DIR/keyword-if-as-identifier.rs:4:9 + | +LL | let if = "foo"; + | ^^ expected identifier, found keyword + | +help: escape `if` to use it as an identifier + | +LL | let r#if = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-impl-as-identifier.rs b/src/test/ui/parser/keyword-impl-as-identifier.rs new file mode 100644 index 000000000..df529bae0 --- /dev/null +++ b/src/test/ui/parser/keyword-impl-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl' + +fn main() { + let impl = "foo"; //~ error: expected identifier, found keyword `impl` +} diff --git a/src/test/ui/parser/keyword-impl-as-identifier.stderr b/src/test/ui/parser/keyword-impl-as-identifier.stderr new file mode 100644 index 000000000..73a50bc38 --- /dev/null +++ b/src/test/ui/parser/keyword-impl-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `impl` + --> $DIR/keyword-impl-as-identifier.rs:4:9 + | +LL | let impl = "foo"; + | ^^^^ expected identifier, found keyword + | +help: escape `impl` to use it as an identifier + | +LL | let r#impl = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-in-as-identifier.rs b/src/test/ui/parser/keyword-in-as-identifier.rs new file mode 100644 index 000000000..e4499dea2 --- /dev/null +++ b/src/test/ui/parser/keyword-in-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py in' + +fn main() { + let in = "foo"; //~ error: expected pattern, found keyword `in` +} diff --git a/src/test/ui/parser/keyword-in-as-identifier.stderr b/src/test/ui/parser/keyword-in-as-identifier.stderr new file mode 100644 index 000000000..98332b723 --- /dev/null +++ b/src/test/ui/parser/keyword-in-as-identifier.stderr @@ -0,0 +1,8 @@ +error: expected pattern, found keyword `in` + --> $DIR/keyword-in-as-identifier.rs:4:9 + | +LL | let in = "foo"; + | ^^ expected pattern + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-let-as-identifier.rs b/src/test/ui/parser/keyword-let-as-identifier.rs new file mode 100644 index 000000000..9b1183501 --- /dev/null +++ b/src/test/ui/parser/keyword-let-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py let' + +fn main() { + let let = "foo"; //~ error: expected identifier, found keyword `let` +} diff --git a/src/test/ui/parser/keyword-let-as-identifier.stderr b/src/test/ui/parser/keyword-let-as-identifier.stderr new file mode 100644 index 000000000..86faaed38 --- /dev/null +++ b/src/test/ui/parser/keyword-let-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `let` + --> $DIR/keyword-let-as-identifier.rs:4:9 + | +LL | let let = "foo"; + | ^^^ expected identifier, found keyword + | +help: escape `let` to use it as an identifier + | +LL | let r#let = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-loop-as-identifier.rs b/src/test/ui/parser/keyword-loop-as-identifier.rs new file mode 100644 index 000000000..46914a19b --- /dev/null +++ b/src/test/ui/parser/keyword-loop-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop' + +fn main() { + let loop = "foo"; //~ error: expected identifier, found keyword `loop` +} diff --git a/src/test/ui/parser/keyword-loop-as-identifier.stderr b/src/test/ui/parser/keyword-loop-as-identifier.stderr new file mode 100644 index 000000000..304ad61cc --- /dev/null +++ b/src/test/ui/parser/keyword-loop-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `loop` + --> $DIR/keyword-loop-as-identifier.rs:4:9 + | +LL | let loop = "foo"; + | ^^^^ expected identifier, found keyword + | +help: escape `loop` to use it as an identifier + | +LL | let r#loop = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-match-as-identifier.rs b/src/test/ui/parser/keyword-match-as-identifier.rs new file mode 100644 index 000000000..d3cecb991 --- /dev/null +++ b/src/test/ui/parser/keyword-match-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py match' + +fn main() { + let match = "foo"; //~ error: expected identifier, found keyword `match` +} diff --git a/src/test/ui/parser/keyword-match-as-identifier.stderr b/src/test/ui/parser/keyword-match-as-identifier.stderr new file mode 100644 index 000000000..25ac397fb --- /dev/null +++ b/src/test/ui/parser/keyword-match-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `match` + --> $DIR/keyword-match-as-identifier.rs:4:9 + | +LL | let match = "foo"; + | ^^^^^ expected identifier, found keyword + | +help: escape `match` to use it as an identifier + | +LL | let r#match = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-mod-as-identifier.rs b/src/test/ui/parser/keyword-mod-as-identifier.rs new file mode 100644 index 000000000..b9c7b6c78 --- /dev/null +++ b/src/test/ui/parser/keyword-mod-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod' + +fn main() { + let mod = "foo"; //~ error: expected identifier, found keyword `mod` +} diff --git a/src/test/ui/parser/keyword-mod-as-identifier.stderr b/src/test/ui/parser/keyword-mod-as-identifier.stderr new file mode 100644 index 000000000..d5688e871 --- /dev/null +++ b/src/test/ui/parser/keyword-mod-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `mod` + --> $DIR/keyword-mod-as-identifier.rs:4:9 + | +LL | let mod = "foo"; + | ^^^ expected identifier, found keyword + | +help: escape `mod` to use it as an identifier + | +LL | let r#mod = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-move-as-identifier.rs b/src/test/ui/parser/keyword-move-as-identifier.rs new file mode 100644 index 000000000..65be02e3c --- /dev/null +++ b/src/test/ui/parser/keyword-move-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py move' + +fn main() { + let move = "foo"; //~ error: expected identifier, found keyword `move` +} diff --git a/src/test/ui/parser/keyword-move-as-identifier.stderr b/src/test/ui/parser/keyword-move-as-identifier.stderr new file mode 100644 index 000000000..75653cffc --- /dev/null +++ b/src/test/ui/parser/keyword-move-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `move` + --> $DIR/keyword-move-as-identifier.rs:4:9 + | +LL | let move = "foo"; + | ^^^^ expected identifier, found keyword + | +help: escape `move` to use it as an identifier + | +LL | let r#move = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-mut-as-identifier.rs b/src/test/ui/parser/keyword-mut-as-identifier.rs new file mode 100644 index 000000000..9b919d2b3 --- /dev/null +++ b/src/test/ui/parser/keyword-mut-as-identifier.rs @@ -0,0 +1,3 @@ +fn main() { + let mut = "foo"; //~ error: expected identifier, found `=` +} diff --git a/src/test/ui/parser/keyword-mut-as-identifier.stderr b/src/test/ui/parser/keyword-mut-as-identifier.stderr new file mode 100644 index 000000000..040960835 --- /dev/null +++ b/src/test/ui/parser/keyword-mut-as-identifier.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `=` + --> $DIR/keyword-mut-as-identifier.rs:2:13 + | +LL | let mut = "foo"; + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-override.rs b/src/test/ui/parser/keyword-override.rs new file mode 100644 index 000000000..009bebd7d --- /dev/null +++ b/src/test/ui/parser/keyword-override.rs @@ -0,0 +1,3 @@ +fn main() { + let override = (); //~ ERROR expected identifier, found reserved keyword `override` +} diff --git a/src/test/ui/parser/keyword-override.stderr b/src/test/ui/parser/keyword-override.stderr new file mode 100644 index 000000000..cdb573686 --- /dev/null +++ b/src/test/ui/parser/keyword-override.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `override` + --> $DIR/keyword-override.rs:2:9 + | +LL | let override = (); + | ^^^^^^^^ expected identifier, found reserved keyword + | +help: escape `override` to use it as an identifier + | +LL | let r#override = (); + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-pub-as-identifier.rs b/src/test/ui/parser/keyword-pub-as-identifier.rs new file mode 100644 index 000000000..2b2bb1411 --- /dev/null +++ b/src/test/ui/parser/keyword-pub-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub' + +fn main() { + let pub = "foo"; //~ error: expected identifier, found keyword `pub` +} diff --git a/src/test/ui/parser/keyword-pub-as-identifier.stderr b/src/test/ui/parser/keyword-pub-as-identifier.stderr new file mode 100644 index 000000000..8d513507c --- /dev/null +++ b/src/test/ui/parser/keyword-pub-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `pub` + --> $DIR/keyword-pub-as-identifier.rs:4:9 + | +LL | let pub = "foo"; + | ^^^ expected identifier, found keyword + | +help: escape `pub` to use it as an identifier + | +LL | let r#pub = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-ref-as-identifier.rs b/src/test/ui/parser/keyword-ref-as-identifier.rs new file mode 100644 index 000000000..f5e04b5db --- /dev/null +++ b/src/test/ui/parser/keyword-ref-as-identifier.rs @@ -0,0 +1,3 @@ +fn main() { + let ref = "foo"; //~ error: expected identifier, found `=` +} diff --git a/src/test/ui/parser/keyword-ref-as-identifier.stderr b/src/test/ui/parser/keyword-ref-as-identifier.stderr new file mode 100644 index 000000000..618043d89 --- /dev/null +++ b/src/test/ui/parser/keyword-ref-as-identifier.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `=` + --> $DIR/keyword-ref-as-identifier.rs:2:13 + | +LL | let ref = "foo"; + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-return-as-identifier.rs b/src/test/ui/parser/keyword-return-as-identifier.rs new file mode 100644 index 000000000..e1a2db5e4 --- /dev/null +++ b/src/test/ui/parser/keyword-return-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py return' + +fn main() { + let return = "foo"; //~ error: expected identifier, found keyword `return` +} diff --git a/src/test/ui/parser/keyword-return-as-identifier.stderr b/src/test/ui/parser/keyword-return-as-identifier.stderr new file mode 100644 index 000000000..eeb8e468b --- /dev/null +++ b/src/test/ui/parser/keyword-return-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `return` + --> $DIR/keyword-return-as-identifier.rs:4:9 + | +LL | let return = "foo"; + | ^^^^^^ expected identifier, found keyword + | +help: escape `return` to use it as an identifier + | +LL | let r#return = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-static-as-identifier.rs b/src/test/ui/parser/keyword-static-as-identifier.rs new file mode 100644 index 000000000..423b9854b --- /dev/null +++ b/src/test/ui/parser/keyword-static-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py static' + +fn main() { + let static = "foo"; //~ error: expected identifier, found keyword `static` +} diff --git a/src/test/ui/parser/keyword-static-as-identifier.stderr b/src/test/ui/parser/keyword-static-as-identifier.stderr new file mode 100644 index 000000000..a3213e2f2 --- /dev/null +++ b/src/test/ui/parser/keyword-static-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `static` + --> $DIR/keyword-static-as-identifier.rs:4:9 + | +LL | let static = "foo"; + | ^^^^^^ expected identifier, found keyword + | +help: escape `static` to use it as an identifier + | +LL | let r#static = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-struct-as-identifier.rs b/src/test/ui/parser/keyword-struct-as-identifier.rs new file mode 100644 index 000000000..18cfe1159 --- /dev/null +++ b/src/test/ui/parser/keyword-struct-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct' + +fn main() { + let struct = "foo"; //~ error: expected identifier, found keyword `struct` +} diff --git a/src/test/ui/parser/keyword-struct-as-identifier.stderr b/src/test/ui/parser/keyword-struct-as-identifier.stderr new file mode 100644 index 000000000..b73361a55 --- /dev/null +++ b/src/test/ui/parser/keyword-struct-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `struct` + --> $DIR/keyword-struct-as-identifier.rs:4:9 + | +LL | let struct = "foo"; + | ^^^^^^ expected identifier, found keyword + | +help: escape `struct` to use it as an identifier + | +LL | let r#struct = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-trait-as-identifier.rs b/src/test/ui/parser/keyword-trait-as-identifier.rs new file mode 100644 index 000000000..67f81167d --- /dev/null +++ b/src/test/ui/parser/keyword-trait-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait' + +fn main() { + let trait = "foo"; //~ error: expected identifier, found keyword `trait` +} diff --git a/src/test/ui/parser/keyword-trait-as-identifier.stderr b/src/test/ui/parser/keyword-trait-as-identifier.stderr new file mode 100644 index 000000000..56ef5f606 --- /dev/null +++ b/src/test/ui/parser/keyword-trait-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `trait` + --> $DIR/keyword-trait-as-identifier.rs:4:9 + | +LL | let trait = "foo"; + | ^^^^^ expected identifier, found keyword + | +help: escape `trait` to use it as an identifier + | +LL | let r#trait = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs b/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs new file mode 100644 index 000000000..4fa37bdb0 --- /dev/null +++ b/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs @@ -0,0 +1,5 @@ +// compile-flags: --edition 2018 + +fn main() { + let try = "foo"; //~ error: expected identifier, found reserved keyword `try` +} diff --git a/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr b/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr new file mode 100644 index 000000000..94a106d47 --- /dev/null +++ b/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `try` + --> $DIR/keyword-try-as-identifier-edition2018.rs:4:9 + | +LL | let try = "foo"; + | ^^^ expected identifier, found reserved keyword + | +help: escape `try` to use it as an identifier + | +LL | let r#try = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-type-as-identifier.rs b/src/test/ui/parser/keyword-type-as-identifier.rs new file mode 100644 index 000000000..04adddf72 --- /dev/null +++ b/src/test/ui/parser/keyword-type-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py type' + +fn main() { + let type = "foo"; //~ error: expected identifier, found keyword `type` +} diff --git a/src/test/ui/parser/keyword-type-as-identifier.stderr b/src/test/ui/parser/keyword-type-as-identifier.stderr new file mode 100644 index 000000000..624c1006b --- /dev/null +++ b/src/test/ui/parser/keyword-type-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `type` + --> $DIR/keyword-type-as-identifier.rs:4:9 + | +LL | let type = "foo"; + | ^^^^ expected identifier, found keyword + | +help: escape `type` to use it as an identifier + | +LL | let r#type = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-typeof.rs b/src/test/ui/parser/keyword-typeof.rs new file mode 100644 index 000000000..29dc77d27 --- /dev/null +++ b/src/test/ui/parser/keyword-typeof.rs @@ -0,0 +1,3 @@ +fn main() { + let typeof = (); //~ ERROR expected identifier, found reserved keyword `typeof` +} diff --git a/src/test/ui/parser/keyword-typeof.stderr b/src/test/ui/parser/keyword-typeof.stderr new file mode 100644 index 000000000..4c5324505 --- /dev/null +++ b/src/test/ui/parser/keyword-typeof.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `typeof` + --> $DIR/keyword-typeof.rs:2:9 + | +LL | let typeof = (); + | ^^^^^^ expected identifier, found reserved keyword + | +help: escape `typeof` to use it as an identifier + | +LL | let r#typeof = (); + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-unsafe-as-identifier.rs b/src/test/ui/parser/keyword-unsafe-as-identifier.rs new file mode 100644 index 000000000..0ff6d188c --- /dev/null +++ b/src/test/ui/parser/keyword-unsafe-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe' + +fn main() { + let unsafe = "foo"; //~ error: expected identifier, found keyword `unsafe` +} diff --git a/src/test/ui/parser/keyword-unsafe-as-identifier.stderr b/src/test/ui/parser/keyword-unsafe-as-identifier.stderr new file mode 100644 index 000000000..b552c9cd3 --- /dev/null +++ b/src/test/ui/parser/keyword-unsafe-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `unsafe` + --> $DIR/keyword-unsafe-as-identifier.rs:4:9 + | +LL | let unsafe = "foo"; + | ^^^^^^ expected identifier, found keyword + | +help: escape `unsafe` to use it as an identifier + | +LL | let r#unsafe = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-use-as-identifier.rs b/src/test/ui/parser/keyword-use-as-identifier.rs new file mode 100644 index 000000000..821bedee0 --- /dev/null +++ b/src/test/ui/parser/keyword-use-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py use' + +fn main() { + let use = "foo"; //~ error: expected identifier, found keyword `use` +} diff --git a/src/test/ui/parser/keyword-use-as-identifier.stderr b/src/test/ui/parser/keyword-use-as-identifier.stderr new file mode 100644 index 000000000..630798659 --- /dev/null +++ b/src/test/ui/parser/keyword-use-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `use` + --> $DIR/keyword-use-as-identifier.rs:4:9 + | +LL | let use = "foo"; + | ^^^ expected identifier, found keyword + | +help: escape `use` to use it as an identifier + | +LL | let r#use = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-where-as-identifier.rs b/src/test/ui/parser/keyword-where-as-identifier.rs new file mode 100644 index 000000000..56301bd20 --- /dev/null +++ b/src/test/ui/parser/keyword-where-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py where' + +fn main() { + let where = "foo"; //~ error: expected identifier, found keyword `where` +} diff --git a/src/test/ui/parser/keyword-where-as-identifier.stderr b/src/test/ui/parser/keyword-where-as-identifier.stderr new file mode 100644 index 000000000..9e72f7940 --- /dev/null +++ b/src/test/ui/parser/keyword-where-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `where` + --> $DIR/keyword-where-as-identifier.rs:4:9 + | +LL | let where = "foo"; + | ^^^^^ expected identifier, found keyword + | +help: escape `where` to use it as an identifier + | +LL | let r#where = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword-while-as-identifier.rs b/src/test/ui/parser/keyword-while-as-identifier.rs new file mode 100644 index 000000000..22026d15d --- /dev/null +++ b/src/test/ui/parser/keyword-while-as-identifier.rs @@ -0,0 +1,5 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py while' + +fn main() { + let while = "foo"; //~ error: expected identifier, found keyword `while` +} diff --git a/src/test/ui/parser/keyword-while-as-identifier.stderr b/src/test/ui/parser/keyword-while-as-identifier.stderr new file mode 100644 index 000000000..2bb62105d --- /dev/null +++ b/src/test/ui/parser/keyword-while-as-identifier.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `while` + --> $DIR/keyword-while-as-identifier.rs:4:9 + | +LL | let while = "foo"; + | ^^^^^ expected identifier, found keyword + | +help: escape `while` to use it as an identifier + | +LL | let r#while = "foo"; + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keyword.rs b/src/test/ui/parser/keyword.rs new file mode 100644 index 000000000..1eb7886c5 --- /dev/null +++ b/src/test/ui/parser/keyword.rs @@ -0,0 +1,5 @@ +pub mod break { + //~^ ERROR expected identifier, found keyword `break` +} + +fn main() {} diff --git a/src/test/ui/parser/keyword.stderr b/src/test/ui/parser/keyword.stderr new file mode 100644 index 000000000..ee7d72b39 --- /dev/null +++ b/src/test/ui/parser/keyword.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `break` + --> $DIR/keyword.rs:1:9 + | +LL | pub mod break { + | ^^^^^ expected identifier, found keyword + | +help: escape `break` to use it as an identifier + | +LL | pub mod r#break { + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/keywords-followed-by-double-colon.rs b/src/test/ui/parser/keywords-followed-by-double-colon.rs new file mode 100644 index 000000000..5c7049f7c --- /dev/null +++ b/src/test/ui/parser/keywords-followed-by-double-colon.rs @@ -0,0 +1,8 @@ +fn main() { + struct::foo(); + //~^ ERROR expected identifier +} +fn bar() { + mut::baz(); + //~^ ERROR expected expression, found keyword `mut` +} diff --git a/src/test/ui/parser/keywords-followed-by-double-colon.stderr b/src/test/ui/parser/keywords-followed-by-double-colon.stderr new file mode 100644 index 000000000..4c4d5e5dd --- /dev/null +++ b/src/test/ui/parser/keywords-followed-by-double-colon.stderr @@ -0,0 +1,14 @@ +error: expected identifier, found `::` + --> $DIR/keywords-followed-by-double-colon.rs:2:11 + | +LL | struct::foo(); + | ^^ expected identifier + +error: expected expression, found keyword `mut` + --> $DIR/keywords-followed-by-double-colon.rs:6:5 + | +LL | mut::baz(); + | ^^^ expected expression + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/labeled-no-colon-expr.rs b/src/test/ui/parser/labeled-no-colon-expr.rs new file mode 100644 index 000000000..db9ef52c1 --- /dev/null +++ b/src/test/ui/parser/labeled-no-colon-expr.rs @@ -0,0 +1,17 @@ +#![feature(label_break_value)] + +fn main() { + 'l0 while false {} //~ ERROR labeled expression must be followed by `:` + 'l1 for _ in 0..1 {} //~ ERROR labeled expression must be followed by `:` + 'l2 loop {} //~ ERROR labeled expression must be followed by `:` + 'l3 {} //~ ERROR labeled expression must be followed by `:` + 'l4 0; //~ ERROR labeled expression must be followed by `:` + //~^ ERROR expected `while`, `for`, `loop` or `{` + + macro_rules! m { + ($b:block) => { + 'l5 $b; //~ ERROR cannot use a `block` macro fragment here + } + } + m!({}); //~ ERROR labeled expression must be followed by `:` +} diff --git a/src/test/ui/parser/labeled-no-colon-expr.stderr b/src/test/ui/parser/labeled-no-colon-expr.stderr new file mode 100644 index 000000000..a258bd3cc --- /dev/null +++ b/src/test/ui/parser/labeled-no-colon-expr.stderr @@ -0,0 +1,95 @@ +error: labeled expression must be followed by `:` + --> $DIR/labeled-no-colon-expr.rs:4:5 + | +LL | 'l0 while false {} + | ----^^^^^^^^^^^^^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: labeled expression must be followed by `:` + --> $DIR/labeled-no-colon-expr.rs:5:5 + | +LL | 'l1 for _ in 0..1 {} + | ----^^^^^^^^^^^^^^^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: labeled expression must be followed by `:` + --> $DIR/labeled-no-colon-expr.rs:6:5 + | +LL | 'l2 loop {} + | ----^^^^^^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: labeled expression must be followed by `:` + --> $DIR/labeled-no-colon-expr.rs:7:5 + | +LL | 'l3 {} + | ----^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/labeled-no-colon-expr.rs:8:9 + | +LL | 'l4 0; + | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - 'l4 0; +LL + 0; + | + +error: labeled expression must be followed by `:` + --> $DIR/labeled-no-colon-expr.rs:8:9 + | +LL | 'l4 0; + | ----^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: cannot use a `block` macro fragment here + --> $DIR/labeled-no-colon-expr.rs:13:17 + | +LL | 'l5 $b; + | ----^^ + | | + | the `block` fragment is within this context +... +LL | m!({}); + | ------ in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: labeled expression must be followed by `:` + --> $DIR/labeled-no-colon-expr.rs:16:8 + | +LL | 'l5 $b; + | ---- help: add `:` after the label + | | + | the label +... +LL | m!({}); + | ^^ + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/parser/let-binop.fixed b/src/test/ui/parser/let-binop.fixed new file mode 100644 index 000000000..93f7f97b0 --- /dev/null +++ b/src/test/ui/parser/let-binop.fixed @@ -0,0 +1,10 @@ +// run-rustfix + +fn main() { + let a: i8 = 1; //~ ERROR can't reassign to an uninitialized variable + let _ = a; + let b = 1; //~ ERROR can't reassign to an uninitialized variable + let _ = b; + let c = 1; //~ ERROR can't reassign to an uninitialized variable + let _ = c; +} diff --git a/src/test/ui/parser/let-binop.rs b/src/test/ui/parser/let-binop.rs new file mode 100644 index 000000000..2adbceae5 --- /dev/null +++ b/src/test/ui/parser/let-binop.rs @@ -0,0 +1,10 @@ +// run-rustfix + +fn main() { + let a: i8 *= 1; //~ ERROR can't reassign to an uninitialized variable + let _ = a; + let b += 1; //~ ERROR can't reassign to an uninitialized variable + let _ = b; + let c *= 1; //~ ERROR can't reassign to an uninitialized variable + let _ = c; +} diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr new file mode 100644 index 000000000..dd33e9157 --- /dev/null +++ b/src/test/ui/parser/let-binop.stderr @@ -0,0 +1,26 @@ +error: can't reassign to an uninitialized variable + --> $DIR/let-binop.rs:4:15 + | +LL | let a: i8 *= 1; + | ^^ help: initialize the variable + | + = help: if you meant to overwrite, remove the `let` binding + +error: can't reassign to an uninitialized variable + --> $DIR/let-binop.rs:6:11 + | +LL | let b += 1; + | ^^ help: initialize the variable + | + = help: if you meant to overwrite, remove the `let` binding + +error: can't reassign to an uninitialized variable + --> $DIR/let-binop.rs:8:11 + | +LL | let c *= 1; + | ^^ help: initialize the variable + | + = help: if you meant to overwrite, remove the `let` binding + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/lifetime-in-pattern-recover.rs b/src/test/ui/parser/lifetime-in-pattern-recover.rs new file mode 100644 index 000000000..7fb14b800 --- /dev/null +++ b/src/test/ui/parser/lifetime-in-pattern-recover.rs @@ -0,0 +1,6 @@ +fn main() { + let &'a x = &0; //~ ERROR unexpected lifetime `'a` in pattern + let &'a mut y = &mut 0; //~ ERROR unexpected lifetime `'a` in pattern + + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/lifetime-in-pattern-recover.stderr b/src/test/ui/parser/lifetime-in-pattern-recover.stderr new file mode 100644 index 000000000..4bf7f57bf --- /dev/null +++ b/src/test/ui/parser/lifetime-in-pattern-recover.stderr @@ -0,0 +1,23 @@ +error: unexpected lifetime `'a` in pattern + --> $DIR/lifetime-in-pattern-recover.rs:2:10 + | +LL | let &'a x = &0; + | ^^ help: remove the lifetime + +error: unexpected lifetime `'a` in pattern + --> $DIR/lifetime-in-pattern-recover.rs:3:10 + | +LL | let &'a mut y = &mut 0; + | ^^ help: remove the lifetime + +error[E0308]: mismatched types + --> $DIR/lifetime-in-pattern-recover.rs:5:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/lifetime-in-pattern.rs b/src/test/ui/parser/lifetime-in-pattern.rs new file mode 100644 index 000000000..d3c638d0c --- /dev/null +++ b/src/test/ui/parser/lifetime-in-pattern.rs @@ -0,0 +1,7 @@ +fn test(&'a str) { + //~^ ERROR unexpected lifetime `'a` in pattern + //~| ERROR expected one of `:`, `@`, or `|`, found `)` +} + +fn main() { +} diff --git a/src/test/ui/parser/lifetime-in-pattern.stderr b/src/test/ui/parser/lifetime-in-pattern.stderr new file mode 100644 index 000000000..a1d721e74 --- /dev/null +++ b/src/test/ui/parser/lifetime-in-pattern.stderr @@ -0,0 +1,28 @@ +error: unexpected lifetime `'a` in pattern + --> $DIR/lifetime-in-pattern.rs:1:10 + | +LL | fn test(&'a str) { + | ^^ help: remove the lifetime + +error: expected one of `:`, `@`, or `|`, found `)` + --> $DIR/lifetime-in-pattern.rs:1:16 + | +LL | fn test(&'a str) { + | ^ expected one of `:`, `@`, or `|` + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn test(self: &'a str) { + | +++++ +help: if this is a parameter name, give it a type + | +LL | fn test(str: &TypeName) { + | ~~~~~~~~~~~~~~ +help: if this is a type, explicitly ignore the parameter name + | +LL | fn test(_: &'a str) { + | ++ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/lifetime-semicolon.fixed b/src/test/ui/parser/lifetime-semicolon.fixed new file mode 100644 index 000000000..482b77046 --- /dev/null +++ b/src/test/ui/parser/lifetime-semicolon.fixed @@ -0,0 +1,10 @@ +// run-rustfix +#![allow(unused)] +struct Foo<'a, 'b> { + a: &'a &'b i32 +} + +fn foo<'a, 'b>(_x: &mut Foo<'a, 'b>) {} +//~^ ERROR expected one of `,` or `>`, found `;` + +fn main() {} diff --git a/src/test/ui/parser/lifetime-semicolon.rs b/src/test/ui/parser/lifetime-semicolon.rs new file mode 100644 index 000000000..21c8b0a7f --- /dev/null +++ b/src/test/ui/parser/lifetime-semicolon.rs @@ -0,0 +1,10 @@ +// run-rustfix +#![allow(unused)] +struct Foo<'a, 'b> { + a: &'a &'b i32 +} + +fn foo<'a, 'b>(_x: &mut Foo<'a; 'b>) {} +//~^ ERROR expected one of `,` or `>`, found `;` + +fn main() {} diff --git a/src/test/ui/parser/lifetime-semicolon.stderr b/src/test/ui/parser/lifetime-semicolon.stderr new file mode 100644 index 000000000..ee486c236 --- /dev/null +++ b/src/test/ui/parser/lifetime-semicolon.stderr @@ -0,0 +1,13 @@ +error: expected one of `,` or `>`, found `;` + --> $DIR/lifetime-semicolon.rs:7:31 + | +LL | fn foo<'a, 'b>(_x: &mut Foo<'a; 'b>) {} + | ^ expected one of `,` or `>` + | +help: use a comma to separate type parameters + | +LL | fn foo<'a, 'b>(_x: &mut Foo<'a, 'b>) {} + | ~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/lifetime_starts_expressions.rs b/src/test/ui/parser/lifetime_starts_expressions.rs new file mode 100644 index 000000000..903b4de6e --- /dev/null +++ b/src/test/ui/parser/lifetime_starts_expressions.rs @@ -0,0 +1,39 @@ +#![allow(unused, dead_code)] + +fn foo() -> u32 { + return 'label: loop { break 'label 42; }; +} + +fn bar() -> u32 { + loop { break 'label: loop { break 'label 42; }; } + //~^ ERROR: parentheses are required around this expression to avoid confusion + //~| HELP: wrap the expression in parentheses +} + +fn baz() -> u32 { + 'label: loop { + break 'label + //~^ WARNING: this labeled break expression is easy to confuse with an unlabeled break + loop { break 42; }; + //~^ HELP: wrap this expression in parentheses + }; + + 'label2: loop { + break 'label2 'inner: loop { break 42; }; + // no warnings or errors here + } +} + +pub fn main() { + // Regression test for issue #86948, as resolved in #87026: + let a = 'first_loop: loop { + break 'first_loop 1; + }; + let b = loop { + break 'inner_loop: loop { + //~^ ERROR: parentheses are required around this expression to avoid confusion + //~| HELP: wrap the expression in parentheses + break 'inner_loop 1; + }; + }; +} diff --git a/src/test/ui/parser/lifetime_starts_expressions.stderr b/src/test/ui/parser/lifetime_starts_expressions.stderr new file mode 100644 index 000000000..82e274325 --- /dev/null +++ b/src/test/ui/parser/lifetime_starts_expressions.stderr @@ -0,0 +1,47 @@ +error: parentheses are required around this expression to avoid confusion with a labeled break expression + --> $DIR/lifetime_starts_expressions.rs:8:18 + | +LL | loop { break 'label: loop { break 'label 42; }; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: wrap the expression in parentheses + | +LL | loop { break ('label: loop { break 'label 42; }); } + | + + + +error: parentheses are required around this expression to avoid confusion with a labeled break expression + --> $DIR/lifetime_starts_expressions.rs:33:15 + | +LL | break 'inner_loop: loop { + | _______________^ +LL | | +LL | | +LL | | break 'inner_loop 1; +LL | | }; + | |_________^ + | +help: wrap the expression in parentheses + | +LL ~ break ('inner_loop: loop { +LL | +LL | +LL | break 'inner_loop 1; +LL ~ }); + | + +warning: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression + --> $DIR/lifetime_starts_expressions.rs:15:9 + | +LL | / break 'label +LL | | +LL | | loop { break 42; }; + | |______________________________^ + | + = note: `#[warn(break_with_label_and_loop)]` on by default +help: wrap this expression in parentheses + | +LL | (loop { break 42; }); + | + + + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.rs b/src/test/ui/parser/macro-bad-delimiter-ident.rs new file mode 100644 index 000000000..f461f06b4 --- /dev/null +++ b/src/test/ui/parser/macro-bad-delimiter-ident.rs @@ -0,0 +1,3 @@ +fn main() { + foo! bar < //~ ERROR expected one of `(`, `[`, or `{`, found `bar` +} diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.stderr b/src/test/ui/parser/macro-bad-delimiter-ident.stderr new file mode 100644 index 000000000..f2365fed2 --- /dev/null +++ b/src/test/ui/parser/macro-bad-delimiter-ident.stderr @@ -0,0 +1,8 @@ +error: expected one of `(`, `[`, or `{`, found `bar` + --> $DIR/macro-bad-delimiter-ident.rs:2:10 + | +LL | foo! bar < + | ^^^ expected one of `(`, `[`, or `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro-braces-dot-question.rs b/src/test/ui/parser/macro-braces-dot-question.rs new file mode 100644 index 000000000..016b434a6 --- /dev/null +++ b/src/test/ui/parser/macro-braces-dot-question.rs @@ -0,0 +1,11 @@ +// check-pass + +use std::io::Write; + +fn main() -> Result<(), std::io::Error> { + vec! { 1, 2, 3 }.len(); + write! { vec![], "" }?; + println!{""} + [0]; // separate statement, not indexing into the result of println. + Ok(()) +} diff --git a/src/test/ui/parser/macro-keyword.rs b/src/test/ui/parser/macro-keyword.rs new file mode 100644 index 000000000..58489fb2c --- /dev/null +++ b/src/test/ui/parser/macro-keyword.rs @@ -0,0 +1,5 @@ +fn macro() { //~ ERROR expected identifier, found reserved keyword `macro` +} + +pub fn main() { +} diff --git a/src/test/ui/parser/macro-keyword.stderr b/src/test/ui/parser/macro-keyword.stderr new file mode 100644 index 000000000..d794671f8 --- /dev/null +++ b/src/test/ui/parser/macro-keyword.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `macro` + --> $DIR/macro-keyword.rs:1:4 + | +LL | fn macro() { + | ^^^^^ expected identifier, found reserved keyword + | +help: escape `macro` to use it as an identifier + | +LL | fn r#macro() { + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro-mismatched-delim-brace-paren.rs b/src/test/ui/parser/macro-mismatched-delim-brace-paren.rs new file mode 100644 index 000000000..404aa7b80 --- /dev/null +++ b/src/test/ui/parser/macro-mismatched-delim-brace-paren.rs @@ -0,0 +1,7 @@ +macro_rules! foo { ($($tt:tt)*) => () } + +fn main() { + foo! { + bar, "baz", 1, 2.0 + ) //~ ERROR mismatched closing delimiter +} diff --git a/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr b/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr new file mode 100644 index 000000000..077d31800 --- /dev/null +++ b/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr @@ -0,0 +1,11 @@ +error: mismatched closing delimiter: `)` + --> $DIR/macro-mismatched-delim-brace-paren.rs:4:10 + | +LL | foo! { + | ^ unclosed delimiter +LL | bar, "baz", 1, 2.0 +LL | ) + | ^ mismatched closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro-mismatched-delim-paren-brace.rs b/src/test/ui/parser/macro-mismatched-delim-paren-brace.rs new file mode 100644 index 000000000..1a1b9edfb --- /dev/null +++ b/src/test/ui/parser/macro-mismatched-delim-paren-brace.rs @@ -0,0 +1,5 @@ +fn main() { + foo! ( + bar, "baz", 1, 2.0 + } //~ ERROR mismatched closing delimiter +} //~ ERROR unexpected closing delimiter: `}` diff --git a/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr new file mode 100644 index 000000000..967a3e6fd --- /dev/null +++ b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr @@ -0,0 +1,22 @@ +error: unexpected closing delimiter: `}` + --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1 + | +LL | fn main() { + | - this opening brace... +... +LL | } + | - ...matches this closing brace +LL | } + | ^ unexpected closing delimiter + +error: mismatched closing delimiter: `}` + --> $DIR/macro-mismatched-delim-paren-brace.rs:2:10 + | +LL | foo! ( + | ^ unclosed delimiter +LL | bar, "baz", 1, 2.0 +LL | } + | ^ mismatched closing delimiter + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/macro/bad-macro-argument.rs b/src/test/ui/parser/macro/bad-macro-argument.rs new file mode 100644 index 000000000..4b6d23890 --- /dev/null +++ b/src/test/ui/parser/macro/bad-macro-argument.rs @@ -0,0 +1,4 @@ +fn main() { + let message = "world"; + println!("Hello, {}", message/); //~ ERROR expected expression +} diff --git a/src/test/ui/parser/macro/bad-macro-argument.stderr b/src/test/ui/parser/macro/bad-macro-argument.stderr new file mode 100644 index 000000000..3cd8accb6 --- /dev/null +++ b/src/test/ui/parser/macro/bad-macro-argument.stderr @@ -0,0 +1,8 @@ +error: expected expression, found end of macro arguments + --> $DIR/bad-macro-argument.rs:3:35 + | +LL | println!("Hello, {}", message/); + | ^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs new file mode 100644 index 000000000..069d181e9 --- /dev/null +++ b/src/test/ui/parser/macro/issue-33569.rs @@ -0,0 +1,12 @@ +macro_rules! foo { + { $+ } => { //~ ERROR expected identifier, found `+` + //~^ ERROR missing fragment specifier + //~| ERROR missing fragment specifier + //~| WARN this was previously accepted + $(x)(y) //~ ERROR expected one of: `*`, `+`, or `?` + } +} + +foo!(); + +fn main() {} diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr new file mode 100644 index 000000000..39d49fd03 --- /dev/null +++ b/src/test/ui/parser/macro/issue-33569.stderr @@ -0,0 +1,30 @@ +error: expected identifier, found `+` + --> $DIR/issue-33569.rs:2:8 + | +LL | { $+ } => { + | ^ + +error: expected one of: `*`, `+`, or `?` + --> $DIR/issue-33569.rs:6:13 + | +LL | $(x)(y) + | ^^^ + +error: missing fragment specifier + --> $DIR/issue-33569.rs:2:8 + | +LL | { $+ } => { + | ^ + +error: missing fragment specifier + --> $DIR/issue-33569.rs:2:8 + | +LL | { $+ } => { + | ^ + | + = note: `#[deny(missing_fragment_specifier)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/macro/issue-37113.rs b/src/test/ui/parser/macro/issue-37113.rs new file mode 100644 index 000000000..0044aa561 --- /dev/null +++ b/src/test/ui/parser/macro/issue-37113.rs @@ -0,0 +1,11 @@ +macro_rules! test_macro { + ( $( $t:ty ),* $(),*) => { + enum SomeEnum { + $( $t, )* //~ ERROR expected identifier, found `String` + }; + }; +} + +fn main() { + test_macro!(String,); +} diff --git a/src/test/ui/parser/macro/issue-37113.stderr b/src/test/ui/parser/macro/issue-37113.stderr new file mode 100644 index 000000000..0912858dd --- /dev/null +++ b/src/test/ui/parser/macro/issue-37113.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `String` + --> $DIR/issue-37113.rs:4:16 + | +LL | $( $t, )* + | ^^ expected identifier +... +LL | test_macro!(String,); + | -------------------- in this macro invocation + | + = note: this error originates in the macro `test_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro/issue-37234.rs b/src/test/ui/parser/macro/issue-37234.rs new file mode 100644 index 000000000..4debc7479 --- /dev/null +++ b/src/test/ui/parser/macro/issue-37234.rs @@ -0,0 +1,9 @@ +macro_rules! failed { + () => {{ + let x = 5 ""; //~ ERROR found `""` + }} +} + +fn main() { + failed!(); +} diff --git a/src/test/ui/parser/macro/issue-37234.stderr b/src/test/ui/parser/macro/issue-37234.stderr new file mode 100644 index 000000000..d79196204 --- /dev/null +++ b/src/test/ui/parser/macro/issue-37234.stderr @@ -0,0 +1,13 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `""` + --> $DIR/issue-37234.rs:3:19 + | +LL | let x = 5 ""; + | ^^ expected one of `.`, `;`, `?`, `else`, or an operator +... +LL | failed!(); + | --------- in this macro invocation + | + = note: this error originates in the macro `failed` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.rs b/src/test/ui/parser/macro/literals-are-validated-before-expansion.rs new file mode 100644 index 000000000..c3fc754b5 --- /dev/null +++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.rs @@ -0,0 +1,10 @@ +macro_rules! black_hole { + ($($tt:tt)*) => {} +} + +fn main() { + black_hole! { '\u{FFFFFF}' } + //~^ ERROR: invalid unicode character escape + black_hole! { "this is surrogate: \u{DAAA}" } + //~^ ERROR: invalid unicode character escape +} diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr new file mode 100644 index 000000000..e874f6249 --- /dev/null +++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr @@ -0,0 +1,18 @@ +error: invalid unicode character escape + --> $DIR/literals-are-validated-before-expansion.rs:6:20 + | +LL | black_hole! { '\u{FFFFFF}' } + | ^^^^^^^^^^ invalid escape + | + = help: unicode escape must be at most 10FFFF + +error: invalid unicode character escape + --> $DIR/literals-are-validated-before-expansion.rs:8:39 + | +LL | black_hole! { "this is surrogate: \u{DAAA}" } + | ^^^^^^^^ invalid escape + | + = help: unicode escape must not be a surrogate + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.rs b/src/test/ui/parser/macro/macro-doc-comments-1.rs new file mode 100644 index 000000000..8d8103bb1 --- /dev/null +++ b/src/test/ui/parser/macro/macro-doc-comments-1.rs @@ -0,0 +1,9 @@ +macro_rules! outer { + (#[$outer:meta]) => () +} + +outer! { + //! Inner +} //~^ ERROR no rules expected the token `!` + +fn main() { } diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.stderr b/src/test/ui/parser/macro/macro-doc-comments-1.stderr new file mode 100644 index 000000000..0ebf3d52b --- /dev/null +++ b/src/test/ui/parser/macro/macro-doc-comments-1.stderr @@ -0,0 +1,14 @@ +error: no rules expected the token `!` + --> $DIR/macro-doc-comments-1.rs:6:5 + | +LL | macro_rules! outer { + | ------------------ when calling this macro +... +LL | //! Inner + | ^^^^^^^^^ + | | + | no rules expected this token in macro call + | inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.rs b/src/test/ui/parser/macro/macro-doc-comments-2.rs new file mode 100644 index 000000000..8f33720ae --- /dev/null +++ b/src/test/ui/parser/macro/macro-doc-comments-2.rs @@ -0,0 +1,9 @@ +macro_rules! inner { + (#![$inner:meta]) => () +} + +inner! { + /// Outer +} //~^ ERROR no rules expected the token `[` + +fn main() { } diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.stderr b/src/test/ui/parser/macro/macro-doc-comments-2.stderr new file mode 100644 index 000000000..346d86586 --- /dev/null +++ b/src/test/ui/parser/macro/macro-doc-comments-2.stderr @@ -0,0 +1,14 @@ +error: no rules expected the token `[` + --> $DIR/macro-doc-comments-2.rs:6:5 + | +LL | macro_rules! inner { + | ------------------ when calling this macro +... +LL | /// Outer + | ^^^^^^^^^ + | | + | no rules expected this token in macro call + | outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match + +error: aborting due to previous error + diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.rs b/src/test/ui/parser/macro/macro-incomplete-parse.rs new file mode 100644 index 000000000..544e4aa7b --- /dev/null +++ b/src/test/ui/parser/macro/macro-incomplete-parse.rs @@ -0,0 +1,27 @@ +macro_rules! ignored_item { + () => { + fn foo() {} + fn bar() {} + , //~ ERROR macro expansion ignores token `,` + } +} + +macro_rules! ignored_expr { + () => ( 1, //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,` + + 2 ) +} + +macro_rules! ignored_pat { + () => ( 1, 2 ) //~ ERROR macro expansion ignores token `,` +} + +ignored_item!(); + +fn main() { + ignored_expr!(); + match 1 { + ignored_pat!() => (), + _ => (), + } +} diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.stderr b/src/test/ui/parser/macro/macro-incomplete-parse.stderr new file mode 100644 index 000000000..707417b72 --- /dev/null +++ b/src/test/ui/parser/macro/macro-incomplete-parse.stderr @@ -0,0 +1,35 @@ +error: macro expansion ignores token `,` and any following + --> $DIR/macro-incomplete-parse.rs:5:9 + | +LL | , + | ^ +... +LL | ignored_item!(); + | --------------- caused by the macro expansion here + | + = note: the usage of `ignored_item!` is likely invalid in item context + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,` + --> $DIR/macro-incomplete-parse.rs:10:14 + | +LL | () => ( 1, + | ^ expected one of `.`, `;`, `?`, `}`, or an operator +... +LL | ignored_expr!(); + | --------------- in this macro invocation + | + = note: this error originates in the macro `ignored_expr` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: macro expansion ignores token `,` and any following + --> $DIR/macro-incomplete-parse.rs:16:14 + | +LL | () => ( 1, 2 ) + | ^ +... +LL | ignored_pat!() => (), + | -------------- caused by the macro expansion here + | + = note: the usage of `ignored_pat!` is likely invalid in pattern context + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/macro/macro-repeat.rs b/src/test/ui/parser/macro/macro-repeat.rs new file mode 100644 index 000000000..3ffbea217 --- /dev/null +++ b/src/test/ui/parser/macro/macro-repeat.rs @@ -0,0 +1,12 @@ +macro_rules! mac { + ( $($v:tt)* ) => { + $v + //~^ ERROR still repeating at this depth + //~| ERROR still repeating at this depth + }; +} + +fn main() { + mac!(0); + mac!(1); +} diff --git a/src/test/ui/parser/macro/macro-repeat.stderr b/src/test/ui/parser/macro/macro-repeat.stderr new file mode 100644 index 000000000..63554b197 --- /dev/null +++ b/src/test/ui/parser/macro/macro-repeat.stderr @@ -0,0 +1,14 @@ +error: variable 'v' is still repeating at this depth + --> $DIR/macro-repeat.rs:3:9 + | +LL | $v + | ^^ + +error: variable 'v' is still repeating at this depth + --> $DIR/macro-repeat.rs:3:9 + | +LL | $v + | ^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/macro/pub-item-macro.rs b/src/test/ui/parser/macro/pub-item-macro.rs new file mode 100644 index 000000000..f5f8a01e6 --- /dev/null +++ b/src/test/ui/parser/macro/pub-item-macro.rs @@ -0,0 +1,21 @@ +// Issue #14660 + +macro_rules! priv_x { + () => { + static x: u32 = 0; + }; +} + +macro_rules! pub_x { () => { + pub priv_x!(); //~ ERROR can't qualify macro invocation with `pub` + //~^ HELP remove the visibility + //~| HELP try adjusting the macro to put `pub` inside the invocation +}} + +mod foo { + pub_x!(); +} + +fn main() { + let y: u32 = foo::x; //~ ERROR static `x` is private +} diff --git a/src/test/ui/parser/macro/pub-item-macro.stderr b/src/test/ui/parser/macro/pub-item-macro.stderr new file mode 100644 index 000000000..9a2fffcce --- /dev/null +++ b/src/test/ui/parser/macro/pub-item-macro.stderr @@ -0,0 +1,31 @@ +error: can't qualify macro invocation with `pub` + --> $DIR/pub-item-macro.rs:10:5 + | +LL | pub priv_x!(); + | ^^^ help: remove the visibility +... +LL | pub_x!(); + | -------- in this macro invocation + | + = help: try adjusting the macro to put `pub` inside the invocation + = note: this error originates in the macro `pub_x` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0603]: static `x` is private + --> $DIR/pub-item-macro.rs:20:23 + | +LL | let y: u32 = foo::x; + | ^ private static + | +note: the static `x` is defined here + --> $DIR/pub-item-macro.rs:5:9 + | +LL | static x: u32 = 0; + | ^^^^^^^^^^^^^^^^^^ +... +LL | pub_x!(); + | -------- in this macro invocation + = note: this error originates in the macro `priv_x` which comes from the expansion of the macro `pub_x` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/parser/macro/trait-non-item-macros.rs b/src/test/ui/parser/macro/trait-non-item-macros.rs new file mode 100644 index 000000000..97fb564bf --- /dev/null +++ b/src/test/ui/parser/macro/trait-non-item-macros.rs @@ -0,0 +1,13 @@ +macro_rules! bah { + ($a:expr) => { + $a + }; //~^ ERROR macro expansion ignores token `2` and any following +} + +trait Bar { + bah!(2); +} + +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/macro/trait-non-item-macros.stderr b/src/test/ui/parser/macro/trait-non-item-macros.stderr new file mode 100644 index 000000000..db20e6b24 --- /dev/null +++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr @@ -0,0 +1,22 @@ +error: macro expansion ignores token `2` and any following + --> $DIR/trait-non-item-macros.rs:3:9 + | +LL | $a + | ^^ +... +LL | bah!(2); + | ------- caused by the macro expansion here + | + = note: the usage of `bah!` is likely invalid in trait item context + +error[E0308]: mismatched types + --> $DIR/trait-non-item-macros.rs:12:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.rs b/src/test/ui/parser/macro/trait-object-macro-matcher.rs new file mode 100644 index 000000000..560195977 --- /dev/null +++ b/src/test/ui/parser/macro/trait-object-macro-matcher.rs @@ -0,0 +1,14 @@ +// A single lifetime is not parsed as a type. +// `ty` matcher in particular doesn't accept a single lifetime + +macro_rules! m { + ($t: ty) => { + let _: $t; + }; +} + +fn main() { + m!('static); + //~^ ERROR lifetime in trait object type must be followed by `+` + //~| ERROR at least one trait is required for an object type +} diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr new file mode 100644 index 000000000..40082564b --- /dev/null +++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr @@ -0,0 +1,15 @@ +error: lifetime in trait object type must be followed by `+` + --> $DIR/trait-object-macro-matcher.rs:11:8 + | +LL | m!('static); + | ^^^^^^^ + +error[E0224]: at least one trait is required for an object type + --> $DIR/trait-object-macro-matcher.rs:11:8 + | +LL | m!('static); + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs new file mode 100644 index 000000000..3afc275d6 --- /dev/null +++ b/src/test/ui/parser/macros-no-semicolon-items.rs @@ -0,0 +1,15 @@ +macro_rules! foo() //~ ERROR semicolon + //~| ERROR unexpected end of macro + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( //~ ERROR semicolon + blah + blah + blah +) + +fn main() { +} diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr new file mode 100644 index 000000000..6d2431c4a --- /dev/null +++ b/src/test/ui/parser/macros-no-semicolon-items.stderr @@ -0,0 +1,47 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:1:17 + | +LL | macro_rules! foo() + | ^^ + | +help: change the delimiters to curly braces + | +LL | macro_rules! foo{} + | ~~ +help: add a semicolon + | +LL | macro_rules! foo(); + | + + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:8:5 + | +LL | bar!( + | _____^ +LL | | blah +LL | | blah +LL | | blah +LL | | ) + | |_^ + | +help: change the delimiters to curly braces + | +LL ~ bar!{ +LL | blah +LL | blah +LL | blah +LL + } + | +help: add a semicolon + | +LL | ); + | + + +error: unexpected end of macro invocation + --> $DIR/macros-no-semicolon-items.rs:1:1 + | +LL | macro_rules! foo() + | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/macros-no-semicolon.rs b/src/test/ui/parser/macros-no-semicolon.rs new file mode 100644 index 000000000..24d1ae9e6 --- /dev/null +++ b/src/test/ui/parser/macros-no-semicolon.rs @@ -0,0 +1,5 @@ +fn main() { + assert_eq!(1, 2) //~ ERROR: expected `;` + assert_eq!(3, 4) //~ ERROR: expected `;` + println!("hello"); +} diff --git a/src/test/ui/parser/macros-no-semicolon.stderr b/src/test/ui/parser/macros-no-semicolon.stderr new file mode 100644 index 000000000..f310662db --- /dev/null +++ b/src/test/ui/parser/macros-no-semicolon.stderr @@ -0,0 +1,18 @@ +error: expected `;`, found `assert_eq` + --> $DIR/macros-no-semicolon.rs:2:21 + | +LL | assert_eq!(1, 2) + | ^ help: add `;` here +LL | assert_eq!(3, 4) + | --------- unexpected token + +error: expected `;`, found `println` + --> $DIR/macros-no-semicolon.rs:3:21 + | +LL | assert_eq!(3, 4) + | ^ help: add `;` here +LL | println!("hello"); + | ------- unexpected token + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/match-arm-without-braces.rs b/src/test/ui/parser/match-arm-without-braces.rs new file mode 100644 index 000000000..bba38fd0f --- /dev/null +++ b/src/test/ui/parser/match-arm-without-braces.rs @@ -0,0 +1,87 @@ +struct S; + +impl S { + fn get<K, V: Default>(_: K) -> Option<V> { + Default::default() + } +} + +enum Val { + Foo, + Bar, +} + +impl Default for Val { + fn default() -> Self { + Val::Foo + } +} + +fn main() { + match S::get(1) { + Some(Val::Foo) => {} + _ => {} + } + match S::get(2) { + Some(Val::Foo) => 3; //~ ERROR `match` arm body without braces + _ => 4, + } + match S::get(5) { + Some(Val::Foo) => + 7; //~ ERROR `match` arm body without braces + 8; + _ => 9, + } + match S::get(10) { + Some(Val::Foo) => + 11; //~ ERROR `match` arm body without braces + 12; + _ => (), + } + match S::get(13) { + None => {} + Some(Val::Foo) => + 14; //~ ERROR `match` arm body without braces + 15; + } + match S::get(16) { + Some(Val::Foo) => 17 //~ ERROR expected `,` following `match` arm + _ => 18, + }; + match S::get(19) { + Some(Val::Foo) => + 20; //~ ERROR `match` arm body without braces + 21 + _ => 22, + } + match S::get(23) { + Some(Val::Foo) => + 24; //~ ERROR `match` arm body without braces + 25 + _ => (), + } + match S::get(26) { + None => {} + Some(Val::Foo) => + 27; //~ ERROR `match` arm body without braces + 28 + } + match S::get(29) { + Some(Val::Foo) => + 30; //~ ERROR expected one of + 31, + _ => 32, + } + match S::get(33) { + Some(Val::Foo) => + 34; //~ ERROR expected one of + 35, + _ => (), + } + match S::get(36) { + None => {} + Some(Val::Foo) => + 37; //~ ERROR expected one of + 38, + } +} diff --git a/src/test/ui/parser/match-arm-without-braces.stderr b/src/test/ui/parser/match-arm-without-braces.stderr new file mode 100644 index 000000000..37d55aa53 --- /dev/null +++ b/src/test/ui/parser/match-arm-without-braces.stderr @@ -0,0 +1,131 @@ +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:26:27 + | +LL | Some(Val::Foo) => 3; + | -- ^- help: use a comma to end a `match` arm expression: `,` + | | | + | | this statement is not surrounded by a body + | while parsing the `match` arm starting here + +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:31:11 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | / 7; +LL | | 8; + | |____________^ these statements are not surrounded by a body + | +help: surround the statements with a body + | +LL ~ { 7; +LL ~ 8; } + | + +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:37:11 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | / 11; +LL | | 12; + | |_____________^ these statements are not surrounded by a body + | +help: surround the statements with a body + | +LL ~ { 11; +LL ~ 12; } + | + +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:44:11 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | / 14; +LL | | 15; + | |_____________^ these statements are not surrounded by a body + | +help: surround the statements with a body + | +LL ~ { 14; +LL ~ 15; } + | + +error: expected `,` following `match` arm + --> $DIR/match-arm-without-braces.rs:48:29 + | +LL | Some(Val::Foo) => 17 + | ^ help: missing a comma here to end this `match` arm: `,` + +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:53:11 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | / 20; +LL | | 21 + | |____________^ these statements are not surrounded by a body + | +help: surround the statements with a body + | +LL ~ { 20; +LL ~ 21 } + | + +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:59:11 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | / 24; +LL | | 25 + | |____________^ these statements are not surrounded by a body + | +help: surround the statements with a body + | +LL ~ { 24; +LL ~ 25 } + | + +error: `match` arm body without braces + --> $DIR/match-arm-without-braces.rs:66:11 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | / 27; +LL | | 28 + | |____________^ these statements are not surrounded by a body + | +help: surround the statements with a body + | +LL ~ { 27; +LL ~ 28 } + | + +error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;` + --> $DIR/match-arm-without-braces.rs:71:13 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | 30; + | ^ expected one of `,`, `.`, `?`, `}`, or an operator + +error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;` + --> $DIR/match-arm-without-braces.rs:77:13 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | 34; + | ^ expected one of `,`, `.`, `?`, `}`, or an operator + +error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;` + --> $DIR/match-arm-without-braces.rs:84:13 + | +LL | Some(Val::Foo) => + | -- while parsing the `match` arm starting here +LL | 37; + | ^ expected one of `,`, `.`, `?`, `}`, or an operator + +error: aborting due to 11 previous errors + diff --git a/src/test/ui/parser/match-arrows-block-then-binop.rs b/src/test/ui/parser/match-arrows-block-then-binop.rs new file mode 100644 index 000000000..56c917c74 --- /dev/null +++ b/src/test/ui/parser/match-arrows-block-then-binop.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = match 0 { + 0 => { + 0 + } + 5 //~ ERROR expected pattern, found `+` + }; +} diff --git a/src/test/ui/parser/match-arrows-block-then-binop.stderr b/src/test/ui/parser/match-arrows-block-then-binop.stderr new file mode 100644 index 000000000..cb361a3db --- /dev/null +++ b/src/test/ui/parser/match-arrows-block-then-binop.stderr @@ -0,0 +1,15 @@ +error: expected pattern, found `+` + --> $DIR/match-arrows-block-then-binop.rs:5:9 + | +LL | } + 5 + | ^ expected pattern + | +help: parentheses are required to parse this as an expression + | +LL ~ 0 => ({ +LL | 0 +LL ~ }) + 5 + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/match-refactor-to-expr.fixed b/src/test/ui/parser/match-refactor-to-expr.fixed new file mode 100644 index 000000000..423147b27 --- /dev/null +++ b/src/test/ui/parser/match-refactor-to-expr.fixed @@ -0,0 +1,12 @@ +// run-rustfix + +fn main() { + let foo = + //~ NOTE while parsing this `match` expression + Some(4).unwrap_or(5) + //~^ NOTE expected one of `.`, `?`, `{`, or an operator + ; //~ NOTE unexpected token + //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;` + + println!("{}", foo) +} diff --git a/src/test/ui/parser/match-refactor-to-expr.rs b/src/test/ui/parser/match-refactor-to-expr.rs new file mode 100644 index 000000000..fcba5d044 --- /dev/null +++ b/src/test/ui/parser/match-refactor-to-expr.rs @@ -0,0 +1,12 @@ +// run-rustfix + +fn main() { + let foo = + match //~ NOTE while parsing this `match` expression + Some(4).unwrap_or(5) + //~^ NOTE expected one of `.`, `?`, `{`, or an operator + ; //~ NOTE unexpected token + //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;` + + println!("{}", foo) +} diff --git a/src/test/ui/parser/match-refactor-to-expr.stderr b/src/test/ui/parser/match-refactor-to-expr.stderr new file mode 100644 index 000000000..851bef8f2 --- /dev/null +++ b/src/test/ui/parser/match-refactor-to-expr.stderr @@ -0,0 +1,16 @@ +error: expected one of `.`, `?`, `{`, or an operator, found `;` + --> $DIR/match-refactor-to-expr.rs:8:9 + | +LL | match + | ----- + | | + | while parsing this `match` expression + | help: try removing this `match` +LL | Some(4).unwrap_or(5) + | - expected one of `.`, `?`, `{`, or an operator +LL | +LL | ; + | ^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/ui/parser/mbe_missing_right_paren.rs b/src/test/ui/parser/mbe_missing_right_paren.rs new file mode 100644 index 000000000..689176b3e --- /dev/null +++ b/src/test/ui/parser/mbe_missing_right_paren.rs @@ -0,0 +1,3 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 3 previous errors +macro_rules! abc(ؼ
\ No newline at end of file diff --git a/src/test/ui/parser/mbe_missing_right_paren.stderr b/src/test/ui/parser/mbe_missing_right_paren.stderr new file mode 100644 index 000000000..ccaf77d39 --- /dev/null +++ b/src/test/ui/parser/mbe_missing_right_paren.stderr @@ -0,0 +1,31 @@ +error: this file contains an unclosed delimiter + --> $DIR/mbe_missing_right_paren.rs:3:19 + | +LL | macro_rules! abc(ؼ + | - ^ + | | + | unclosed delimiter + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/mbe_missing_right_paren.rs:3:17 + | +LL | macro_rules! abc(ؼ + | ^^ + | +help: change the delimiters to curly braces + | +LL | macro_rules! abc { /* items */ } + | ~~~~~~~~~~~~~~~ +help: add a semicolon + | +LL | macro_rules! abc(ؼ; + | + + +error: unexpected end of macro invocation + --> $DIR/mbe_missing_right_paren.rs:3:19 + | +LL | macro_rules! abc(ؼ + | ^ missing tokens in macro arguments + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs new file mode 100644 index 000000000..8f46970b1 --- /dev/null +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs @@ -0,0 +1,13 @@ +fn main() {} + +impl T for () { //~ ERROR cannot find trait `T` in this scope + +fn foo(&self) {} + +trait T { //~ ERROR trait is not supported in `trait`s or `impl`s + fn foo(&self); +} + +pub(crate) struct Bar<T>(); //~ ERROR struct is not supported in `trait`s or `impl`s + +//~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr new file mode 100644 index 000000000..cc7cc0c55 --- /dev/null +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr @@ -0,0 +1,34 @@ +error: this file contains an unclosed delimiter + --> $DIR/missing-close-brace-in-impl-trait.rs:13:52 + | +LL | impl T for () { + | - unclosed delimiter +... +LL | + | ^ + +error: trait is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-impl-trait.rs:7:1 + | +LL | trait T { + | ^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-impl-trait.rs:11:1 + | +LL | pub(crate) struct Bar<T>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error[E0405]: cannot find trait `T` in this scope + --> $DIR/missing-close-brace-in-impl-trait.rs:3:6 + | +LL | impl T for () { + | ^ not found in this scope + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs new file mode 100644 index 000000000..090a17b41 --- /dev/null +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs @@ -0,0 +1,13 @@ +pub(crate) struct Bar<T> { + foo: T, + +trait T { //~ ERROR expected identifier, found keyword `trait` + fn foo(&self); +} + + +impl T for Bar<usize> { +fn foo(&self) {} +} + +fn main() {} //~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr new file mode 100644 index 000000000..a47d5506e --- /dev/null +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr @@ -0,0 +1,17 @@ +error: this file contains an unclosed delimiter + --> $DIR/missing-close-brace-in-struct.rs:13:65 + | +LL | pub(crate) struct Bar<T> { + | - unclosed delimiter +... +LL | fn main() {} + | ^ + +error: expected identifier, found keyword `trait` + --> $DIR/missing-close-brace-in-struct.rs:4:1 + | +LL | trait T { + | ^^^^^ expected identifier, found keyword + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs new file mode 100644 index 000000000..b6932deb5 --- /dev/null +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs @@ -0,0 +1,12 @@ +trait T { + fn foo(&self); + +pub(crate) struct Bar<T>(); +//~^ ERROR struct is not supported in `trait`s or `impl`s + +impl T for Bar<usize> { +//~^ ERROR implementation is not supported in `trait`s or `impl`s +fn foo(&self) {} +} + +fn main() {} //~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr new file mode 100644 index 000000000..7c6254356 --- /dev/null +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr @@ -0,0 +1,27 @@ +error: this file contains an unclosed delimiter + --> $DIR/missing-close-brace-in-trait.rs:12:65 + | +LL | trait T { + | - unclosed delimiter +... +LL | fn main() {} + | ^ + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-trait.rs:4:1 + | +LL | pub(crate) struct Bar<T>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-trait.rs:7:1 + | +LL | impl T for Bar<usize> { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.rs b/src/test/ui/parser/mismatched-delim-brace-empty-block.rs new file mode 100644 index 000000000..61d7a9af2 --- /dev/null +++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.rs @@ -0,0 +1,5 @@ +fn main() { + +} + let _ = (); +} //~ ERROR unexpected closing delimiter diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr new file mode 100644 index 000000000..165eb8ae9 --- /dev/null +++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr @@ -0,0 +1,14 @@ +error: unexpected closing delimiter: `}` + --> $DIR/mismatched-delim-brace-empty-block.rs:5:1 + | +LL | fn main() { + | - this opening brace... +LL | +LL | } + | - ...matches this closing brace +LL | let _ = (); +LL | } + | ^ unexpected closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs new file mode 100644 index 000000000..da95c1bfa --- /dev/null +++ b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs @@ -0,0 +1,23 @@ +struct Foo<T1, T2> { + _a : T1, + _b : T2, +} + +fn test1<T>(arg : T) { + let v : Vec<(u32,_) = vec![]; + //~^ ERROR: expected one of + //~| ERROR: type annotations needed +} + +fn test2<T1, T2>(arg1 : T1, arg2 : T2) { + let foo : Foo::<T1, T2 = Foo {_a : arg1, _b : arg2}; + //~^ ERROR: expected one of +} + +fn test3<'a>(arg : &'a u32) { + let v : Vec<'a = vec![]; + //~^ ERROR: expected one of + //~| ERROR: type annotations needed for `Vec<T>` +} + +fn main() {} diff --git a/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr new file mode 100644 index 000000000..bad241634 --- /dev/null +++ b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr @@ -0,0 +1,66 @@ +error: expected one of `,`, `:`, or `>`, found `=` + --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:23 + | +LL | let v : Vec<(u32,_) = vec![]; + | - - ^ expected one of `,`, `:`, or `>` + | | | + | | maybe try to close unmatched angle bracket + | while parsing the type for `v` + | +help: you might have meant to end the type parameters here + | +LL | let v : Vec<(u32,_)> = vec![]; + | + + +error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `{` + --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:13:32 + | +LL | let foo : Foo::<T1, T2 = Foo {_a : arg1, _b : arg2}; + | --- ^ expected one of 7 possible tokens + | | + | while parsing the type for `foo` + | +help: you might have meant to end the type parameters here + | +LL | let foo : Foo::<T1>, T2 = Foo {_a : arg1, _b : arg2}; + | + + +error: expected one of `,`, `:`, or `>`, found `=` + --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:18 + | +LL | let v : Vec<'a = vec![]; + | - -- ^ expected one of `,`, `:`, or `>` + | | | + | | maybe try to close unmatched angle bracket + | while parsing the type for `v` + | +help: you might have meant to end the type parameters here + | +LL | let v : Vec<'a> = vec![]; + | + + +error[E0282]: type annotations needed for `Vec<T>` + --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:7 + | +LL | let v : Vec<(u32,_) = vec![]; + | ^ + | +help: consider giving `v` an explicit type, where the type for type parameter `T` is specified + | +LL | let v: Vec<T> : Vec<(u32,_) = vec![]; + | ++++++++ + +error[E0282]: type annotations needed for `Vec<T>` + --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:7 + | +LL | let v : Vec<'a = vec![]; + | ^ + | +help: consider giving `v` an explicit type, where the type for type parameter `T` is specified + | +LL | let v: Vec<T> : Vec<'a = vec![]; + | ++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs new file mode 100644 index 000000000..d69a56c51 --- /dev/null +++ b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs @@ -0,0 +1,11 @@ +// run-rustifx +#![allow(unused)] +use std::sync::{Arc, Mutex}; + +pub struct Foo { + a: Mutex<usize>, + b: Arc<Mutex<usize>, //~ HELP you might have meant to end the type parameters here + c: Arc<Mutex<usize>>, +} //~ ERROR expected one of + +fn main() {} diff --git a/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr new file mode 100644 index 000000000..46ca1f06b --- /dev/null +++ b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr @@ -0,0 +1,15 @@ +error: expected one of `>`, a const expression, lifetime, or type, found `}` + --> $DIR/missing-closing-angle-bracket-struct-field-ty.rs:9:1 + | +LL | c: Arc<Mutex<usize>>, + | - expected one of `>`, a const expression, lifetime, or type +LL | } + | ^ unexpected token + | +help: you might have meant to end the type parameters here + | +LL | b: Arc<Mutex<usize>>, + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/missing-semicolon.rs b/src/test/ui/parser/missing-semicolon.rs new file mode 100644 index 000000000..f68d177c0 --- /dev/null +++ b/src/test/ui/parser/missing-semicolon.rs @@ -0,0 +1,8 @@ +macro_rules! m { + ($($e1:expr),*; $($e2:expr),*) => { + $( let x = $e1 )*; //~ ERROR expected one of `.`, `;`, `?`, `else`, or + $( println!("{}", $e2) )*; + } +} + +fn main() { m!(0, 0; 0, 0); } diff --git a/src/test/ui/parser/missing-semicolon.stderr b/src/test/ui/parser/missing-semicolon.stderr new file mode 100644 index 000000000..e0d5e84ec --- /dev/null +++ b/src/test/ui/parser/missing-semicolon.stderr @@ -0,0 +1,13 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found keyword `let` + --> $DIR/missing-semicolon.rs:3:12 + | +LL | $( let x = $e1 )*; + | ^^^ expected one of `.`, `;`, `?`, `else`, or an operator +... +LL | fn main() { m!(0, 0; 0, 0); } + | -------------- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/parser/missing_right_paren.rs b/src/test/ui/parser/missing_right_paren.rs new file mode 100644 index 000000000..810dee957 --- /dev/null +++ b/src/test/ui/parser/missing_right_paren.rs @@ -0,0 +1,3 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 4 previous errors +fn main((ؼ
\ No newline at end of file diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr new file mode 100644 index 000000000..3fe0d0f42 --- /dev/null +++ b/src/test/ui/parser/missing_right_paren.stderr @@ -0,0 +1,32 @@ +error: this file contains an unclosed delimiter + --> $DIR/missing_right_paren.rs:3:11 + | +LL | fn main((ؼ + | -- ^ + | || + | |unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/missing_right_paren.rs:3:11 + | +LL | fn main((ؼ + | -- ^ + | || + | |unclosed delimiter + | unclosed delimiter + +error: expected one of `:` or `|`, found `)` + --> $DIR/missing_right_paren.rs:3:11 + | +LL | fn main((ؼ + | ^ expected one of `:` or `|` + +error: expected one of `->`, `where`, or `{`, found `<eof>` + --> $DIR/missing_right_paren.rs:3:11 + | +LL | fn main((ؼ + | ^ expected one of `->`, `where`, or `{` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/misspelled-macro-rules.fixed b/src/test/ui/parser/misspelled-macro-rules.fixed new file mode 100644 index 000000000..62be913d8 --- /dev/null +++ b/src/test/ui/parser/misspelled-macro-rules.fixed @@ -0,0 +1,13 @@ +// Regression test for issue #91227. + +// run-rustfix + +#![allow(unused_macros)] + +macro_rules! thing { +//~^ ERROR: expected one of +//~| HELP: perhaps you meant to define a macro + () => {} +} + +fn main() {} diff --git a/src/test/ui/parser/misspelled-macro-rules.rs b/src/test/ui/parser/misspelled-macro-rules.rs new file mode 100644 index 000000000..4290e6e5e --- /dev/null +++ b/src/test/ui/parser/misspelled-macro-rules.rs @@ -0,0 +1,13 @@ +// Regression test for issue #91227. + +// run-rustfix + +#![allow(unused_macros)] + +marco_rules! thing { +//~^ ERROR: expected one of +//~| HELP: perhaps you meant to define a macro + () => {} +} + +fn main() {} diff --git a/src/test/ui/parser/misspelled-macro-rules.stderr b/src/test/ui/parser/misspelled-macro-rules.stderr new file mode 100644 index 000000000..56df71238 --- /dev/null +++ b/src/test/ui/parser/misspelled-macro-rules.stderr @@ -0,0 +1,10 @@ +error: expected one of `(`, `[`, or `{`, found `thing` + --> $DIR/misspelled-macro-rules.rs:7:14 + | +LL | marco_rules! thing { + | ----------- ^^^^^ expected one of `(`, `[`, or `{` + | | + | help: perhaps you meant to define a macro: `macro_rules` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/mod_file_not_exist.rs b/src/test/ui/parser/mod_file_not_exist.rs new file mode 100644 index 000000000..7b079eb02 --- /dev/null +++ b/src/test/ui/parser/mod_file_not_exist.rs @@ -0,0 +1,9 @@ +// ignore-windows + +mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` +//~^ HELP to create the module `not_a_real_file`, create file + +fn main() { + assert_eq!(mod_file_aux::bar(), 10); + //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux` +} diff --git a/src/test/ui/parser/mod_file_not_exist.stderr b/src/test/ui/parser/mod_file_not_exist.stderr new file mode 100644 index 000000000..62456d518 --- /dev/null +++ b/src/test/ui/parser/mod_file_not_exist.stderr @@ -0,0 +1,18 @@ +error[E0583]: file not found for module `not_a_real_file` + --> $DIR/mod_file_not_exist.rs:3:1 + | +LL | mod not_a_real_file; + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs" + +error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux` + --> $DIR/mod_file_not_exist.rs:7:16 + | +LL | assert_eq!(mod_file_aux::bar(), 10); + | ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0433, E0583. +For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/parser/mod_file_not_exist_windows.rs b/src/test/ui/parser/mod_file_not_exist_windows.rs new file mode 100644 index 000000000..5db21e2bb --- /dev/null +++ b/src/test/ui/parser/mod_file_not_exist_windows.rs @@ -0,0 +1,9 @@ +// only-windows + +mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` +//~^ HELP to create the module `not_a_real_file`, create file + +fn main() { + assert_eq!(mod_file_aux::bar(), 10); + //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux` +} diff --git a/src/test/ui/parser/mod_file_not_exist_windows.stderr b/src/test/ui/parser/mod_file_not_exist_windows.stderr new file mode 100644 index 000000000..d5143dbe9 --- /dev/null +++ b/src/test/ui/parser/mod_file_not_exist_windows.stderr @@ -0,0 +1,18 @@ +error[E0583]: file not found for module `not_a_real_file` + --> $DIR/mod_file_not_exist_windows.rs:3:1 + | +LL | mod not_a_real_file; + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs" + +error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux` + --> $DIR/mod_file_not_exist_windows.rs:7:16 + | +LL | assert_eq!(mod_file_aux::bar(), 10); + | ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0433, E0583. +For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/parser/mod_file_with_path_attr.rs b/src/test/ui/parser/mod_file_with_path_attr.rs new file mode 100644 index 000000000..9450d89e5 --- /dev/null +++ b/src/test/ui/parser/mod_file_with_path_attr.rs @@ -0,0 +1,8 @@ +// normalize-stderr-test: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG (" + +#[path = "not_a_real_file.rs"] +mod m; //~ ERROR not_a_real_file.rs + +fn main() { + assert_eq!(m::foo(), 10); +} diff --git a/src/test/ui/parser/mod_file_with_path_attr.stderr b/src/test/ui/parser/mod_file_with_path_attr.stderr new file mode 100644 index 000000000..cd1add73d --- /dev/null +++ b/src/test/ui/parser/mod_file_with_path_attr.stderr @@ -0,0 +1,8 @@ +error: couldn't read $DIR/not_a_real_file.rs: $FILE_NOT_FOUND_MSG (os error 2) + --> $DIR/mod_file_with_path_attr.rs:4:1 + | +LL | mod m; + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs new file mode 100644 index 000000000..7e7995d67 --- /dev/null +++ b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs @@ -0,0 +1,10 @@ +// Regression test for #80134. + +fn main() { + (()é); + //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator + //~| ERROR: cannot find value `é` in this scope + (()氷); + //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator + //~| ERROR: cannot find value `氷` in this scope +} diff --git a/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr new file mode 100644 index 000000000..21e71aa12 --- /dev/null +++ b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr @@ -0,0 +1,33 @@ +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `é` + --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8 + | +LL | (()é); + | ^ + | | + | expected one of `)`, `,`, `.`, `?`, or an operator + | help: missing `,` + +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `氷` + --> $DIR/multibyte-char-use-seperator-issue-80134.rs:7:8 + | +LL | (()氷); + | -^ + | | + | expected one of `)`, `,`, `.`, `?`, or an operator + | help: missing `,` + +error[E0425]: cannot find value `é` in this scope + --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8 + | +LL | (()é); + | ^ not found in this scope + +error[E0425]: cannot find value `氷` in this scope + --> $DIR/multibyte-char-use-seperator-issue-80134.rs:7:8 + | +LL | (()氷); + | ^^ not found in this scope + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/multiline-comment-line-tracking.rs b/src/test/ui/parser/multiline-comment-line-tracking.rs new file mode 100644 index 000000000..d4735e8a7 --- /dev/null +++ b/src/test/ui/parser/multiline-comment-line-tracking.rs @@ -0,0 +1,9 @@ +// Parse error on line X, but is reported on line Y instead. + +/* 1 + * 2 + * 3 + */ +fn main() { + %; //~ ERROR expected expression, found `%` +} diff --git a/src/test/ui/parser/multiline-comment-line-tracking.stderr b/src/test/ui/parser/multiline-comment-line-tracking.stderr new file mode 100644 index 000000000..cac0c801a --- /dev/null +++ b/src/test/ui/parser/multiline-comment-line-tracking.stderr @@ -0,0 +1,8 @@ +error: expected expression, found `%` + --> $DIR/multiline-comment-line-tracking.rs:8:3 + | +LL | %; + | ^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/multitrait.rs b/src/test/ui/parser/multitrait.rs new file mode 100644 index 000000000..f9b4b37ac --- /dev/null +++ b/src/test/ui/parser/multitrait.rs @@ -0,0 +1,9 @@ +struct S { + y: isize +} + +impl Cmp, ToString for S { +//~^ ERROR: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,` + fn eq(&&other: S) { false } + fn to_string(&self) -> String { "hi".to_string() } +} diff --git a/src/test/ui/parser/multitrait.stderr b/src/test/ui/parser/multitrait.stderr new file mode 100644 index 000000000..5a8bb2f7a --- /dev/null +++ b/src/test/ui/parser/multitrait.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,` + --> $DIR/multitrait.rs:5:9 + | +LL | impl Cmp, ToString for S { + | ^ expected one of 8 possible tokens + +error: aborting due to previous error + diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs new file mode 100644 index 000000000..8b83d6ab2 --- /dev/null +++ b/src/test/ui/parser/mut-patterns.rs @@ -0,0 +1,48 @@ +// Can't put mut in non-ident pattern + +// edition:2018 + +#![feature(box_patterns)] +#![allow(warnings)] + +pub fn main() { + let mut _ = 0; //~ ERROR `mut` must be followed by a named binding + let mut (_, _) = (0, 0); //~ ERROR `mut` must be followed by a named binding + + let mut (x @ y) = 0; //~ ERROR `mut` must be attached to each individual binding + + let mut mut x = 0; + //~^ ERROR `mut` on a binding may not be repeated + //~| remove the additional `mut`s + + struct Foo { x: isize } + let mut Foo { x: x } = Foo { x: 3 }; + //~^ ERROR `mut` must be attached to each individual binding + //~| add `mut` to each binding + + let mut Foo { x } = Foo { x: 3 }; + //~^ ERROR `mut` must be attached to each individual binding + //~| add `mut` to each binding + + struct r#yield(u8, u8); + let mut mut yield(become, await) = r#yield(0, 0); + //~^ ERROR `mut` on a binding may not be repeated + //~| ERROR `mut` must be attached to each individual binding + //~| ERROR expected identifier, found reserved keyword `yield` + //~| ERROR expected identifier, found reserved keyword `become` + //~| ERROR expected identifier, found keyword `await` + + struct W<T, U>(T, U); + struct B { f: Box<u8> } + let mut W(mut a, W(b, W(ref c, W(d, B { box f })))) + //~^ ERROR `mut` must be attached to each individual binding + = W(0, W(1, W(2, W(3, B { f: Box::new(4u8) })))); + + // Make sure we don't accidentally allow `mut $p` where `$p:pat`. + macro_rules! foo { + ($p:pat) => { + let mut $p = 0; //~ ERROR expected identifier, found `x` + } + } + foo!(x); +} diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr new file mode 100644 index 000000000..f179d8c9e --- /dev/null +++ b/src/test/ui/parser/mut-patterns.stderr @@ -0,0 +1,114 @@ +error: `mut` must be followed by a named binding + --> $DIR/mut-patterns.rs:9:9 + | +LL | let mut _ = 0; + | ^^^^^ help: remove the `mut` prefix: `_` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: `mut` must be followed by a named binding + --> $DIR/mut-patterns.rs:10:9 + | +LL | let mut (_, _) = (0, 0); + | ^^^^^^^^^^ help: remove the `mut` prefix: `(_, _)` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: `mut` must be attached to each individual binding + --> $DIR/mut-patterns.rs:12:9 + | +LL | let mut (x @ y) = 0; + | ^^^^^^^^^^^ help: add `mut` to each binding: `(mut x @ mut y)` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: `mut` on a binding may not be repeated + --> $DIR/mut-patterns.rs:14:13 + | +LL | let mut mut x = 0; + | ^^^ help: remove the additional `mut`s + +error: `mut` must be attached to each individual binding + --> $DIR/mut-patterns.rs:19:9 + | +LL | let mut Foo { x: x } = Foo { x: 3 }; + | ^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { x: mut x }` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: `mut` must be attached to each individual binding + --> $DIR/mut-patterns.rs:23:9 + | +LL | let mut Foo { x } = Foo { x: 3 }; + | ^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { mut x }` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: `mut` on a binding may not be repeated + --> $DIR/mut-patterns.rs:28:13 + | +LL | let mut mut yield(become, await) = r#yield(0, 0); + | ^^^ help: remove the additional `mut`s + +error: expected identifier, found reserved keyword `yield` + --> $DIR/mut-patterns.rs:28:17 + | +LL | let mut mut yield(become, await) = r#yield(0, 0); + | ^^^^^ expected identifier, found reserved keyword + | +help: escape `yield` to use it as an identifier + | +LL | let mut mut r#yield(become, await) = r#yield(0, 0); + | ++ + +error: expected identifier, found reserved keyword `become` + --> $DIR/mut-patterns.rs:28:23 + | +LL | let mut mut yield(become, await) = r#yield(0, 0); + | ^^^^^^ expected identifier, found reserved keyword + | +help: escape `become` to use it as an identifier + | +LL | let mut mut yield(r#become, await) = r#yield(0, 0); + | ++ + +error: expected identifier, found keyword `await` + --> $DIR/mut-patterns.rs:28:31 + | +LL | let mut mut yield(become, await) = r#yield(0, 0); + | ^^^^^ expected identifier, found keyword + | +help: escape `await` to use it as an identifier + | +LL | let mut mut yield(become, r#await) = r#yield(0, 0); + | ++ + +error: `mut` must be attached to each individual binding + --> $DIR/mut-patterns.rs:28:9 + | +LL | let mut mut yield(become, await) = r#yield(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `r#yield(mut r#become, mut r#await)` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: `mut` must be attached to each individual binding + --> $DIR/mut-patterns.rs:37:9 + | +LL | let mut W(mut a, W(b, W(ref c, W(d, B { box f })))) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: expected identifier, found `x` + --> $DIR/mut-patterns.rs:44:21 + | +LL | let mut $p = 0; + | ^^ expected identifier +... +LL | foo!(x); + | ------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 13 previous errors + diff --git a/src/test/ui/parser/nested-missing-closing-angle-bracket.rs b/src/test/ui/parser/nested-missing-closing-angle-bracket.rs new file mode 100644 index 000000000..84ffdd176 --- /dev/null +++ b/src/test/ui/parser/nested-missing-closing-angle-bracket.rs @@ -0,0 +1,4 @@ +fn main() { + let v : Vec::<Vec<(u32,_,_)> = vec![vec![]]; + //~^ ERROR: expected one of +} diff --git a/src/test/ui/parser/nested-missing-closing-angle-bracket.stderr b/src/test/ui/parser/nested-missing-closing-angle-bracket.stderr new file mode 100644 index 000000000..b85bc0256 --- /dev/null +++ b/src/test/ui/parser/nested-missing-closing-angle-bracket.stderr @@ -0,0 +1,8 @@ +error: expected one of `,` or `>`, found `;` + --> $DIR/nested-missing-closing-angle-bracket.rs:2:46 + | +LL | let v : Vec::<Vec<(u32,_,_)> = vec![vec![]]; + | - while parsing the type for `v` ^ expected one of `,` or `>` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/new-unicode-escapes-1.rs b/src/test/ui/parser/new-unicode-escapes-1.rs new file mode 100644 index 000000000..d6a54660e --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-1.rs @@ -0,0 +1,3 @@ +pub fn main() { + let s = "\u{2603"; //~ ERROR unterminated unicode escape +} diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr new file mode 100644 index 000000000..d133e46b4 --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-1.stderr @@ -0,0 +1,13 @@ +error: unterminated unicode escape + --> $DIR/new-unicode-escapes-1.rs:2:14 + | +LL | let s = "\u{2603"; + | ^^^^^^^ missing a closing `}` + | +help: terminate the unicode escape + | +LL | let s = "\u{2603}"; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/new-unicode-escapes-2.rs b/src/test/ui/parser/new-unicode-escapes-2.rs new file mode 100644 index 000000000..cbb614c19 --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-2.rs @@ -0,0 +1,3 @@ +pub fn main() { + let s = "\u{260311111111}"; //~ ERROR overlong unicode escape +} diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr new file mode 100644 index 000000000..2f3f8c0f9 --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-2.stderr @@ -0,0 +1,8 @@ +error: overlong unicode escape + --> $DIR/new-unicode-escapes-2.rs:2:14 + | +LL | let s = "\u{260311111111}"; + | ^^^^^^^^^^^^^^^^ must have at most 6 hex digits + +error: aborting due to previous error + diff --git a/src/test/ui/parser/new-unicode-escapes-3.rs b/src/test/ui/parser/new-unicode-escapes-3.rs new file mode 100644 index 000000000..295ab08c0 --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-3.rs @@ -0,0 +1,4 @@ +pub fn main() { + let s1 = "\u{d805}"; //~ ERROR invalid unicode character escape + let s2 = "\u{ffffff}"; //~ ERROR invalid unicode character escape +} diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr new file mode 100644 index 000000000..f5a0f8fc7 --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-3.stderr @@ -0,0 +1,18 @@ +error: invalid unicode character escape + --> $DIR/new-unicode-escapes-3.rs:2:15 + | +LL | let s1 = "\u{d805}"; + | ^^^^^^^^ invalid escape + | + = help: unicode escape must not be a surrogate + +error: invalid unicode character escape + --> $DIR/new-unicode-escapes-3.rs:3:15 + | +LL | let s2 = "\u{ffffff}"; + | ^^^^^^^^^^ invalid escape + | + = help: unicode escape must be at most 10FFFF + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/new-unicode-escapes-4.rs b/src/test/ui/parser/new-unicode-escapes-4.rs new file mode 100644 index 000000000..79882713e --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-4.rs @@ -0,0 +1,4 @@ +pub fn main() { + let s = "\u{lol}"; + //~^ ERROR invalid character in unicode escape: `l` +} diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr new file mode 100644 index 000000000..514591af1 --- /dev/null +++ b/src/test/ui/parser/new-unicode-escapes-4.stderr @@ -0,0 +1,8 @@ +error: invalid character in unicode escape: `l` + --> $DIR/new-unicode-escapes-4.rs:2:17 + | +LL | let s = "\u{lol}"; + | ^ invalid character in unicode escape + +error: aborting due to previous error + diff --git a/src/test/ui/parser/no-binary-float-literal.rs b/src/test/ui/parser/no-binary-float-literal.rs new file mode 100644 index 000000000..e07ff6518 --- /dev/null +++ b/src/test/ui/parser/no-binary-float-literal.rs @@ -0,0 +1,8 @@ +fn main() { + 0b101010f64; + //~^ ERROR binary float literal is not supported + 0b101.010; + //~^ ERROR binary float literal is not supported + 0b101p4f64; + //~^ ERROR invalid suffix `p4f64` for number literal +} diff --git a/src/test/ui/parser/no-binary-float-literal.stderr b/src/test/ui/parser/no-binary-float-literal.stderr new file mode 100644 index 000000000..cfd448684 --- /dev/null +++ b/src/test/ui/parser/no-binary-float-literal.stderr @@ -0,0 +1,22 @@ +error: binary float literal is not supported + --> $DIR/no-binary-float-literal.rs:4:5 + | +LL | 0b101.010; + | ^^^^^^^^^ + +error: binary float literal is not supported + --> $DIR/no-binary-float-literal.rs:2:5 + | +LL | 0b101010f64; + | ^^^^^^^^^^^ not supported + +error: invalid suffix `p4f64` for number literal + --> $DIR/no-binary-float-literal.rs:6:5 + | +LL | 0b101p4f64; + | ^^^^^^^^^^ invalid suffix `p4f64` + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.rs b/src/test/ui/parser/no-const-fn-in-extern-block.rs new file mode 100644 index 000000000..1993124ed --- /dev/null +++ b/src/test/ui/parser/no-const-fn-in-extern-block.rs @@ -0,0 +1,8 @@ +extern "C" { + const fn foo(); + //~^ ERROR functions in `extern` blocks cannot have qualifiers + const unsafe fn bar(); + //~^ ERROR functions in `extern` blocks cannot have qualifiers +} + +fn main() {} diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.stderr b/src/test/ui/parser/no-const-fn-in-extern-block.stderr new file mode 100644 index 000000000..4ac0e2655 --- /dev/null +++ b/src/test/ui/parser/no-const-fn-in-extern-block.stderr @@ -0,0 +1,29 @@ +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/no-const-fn-in-extern-block.rs:2:14 + | +LL | extern "C" { + | ---------- in this `extern` block +LL | const fn foo(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn foo(); + | ~~ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/no-const-fn-in-extern-block.rs:4:21 + | +LL | extern "C" { + | ---------- in this `extern` block +... +LL | const unsafe fn bar(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn bar(); + | ~~ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/no-hex-float-literal.rs b/src/test/ui/parser/no-hex-float-literal.rs new file mode 100644 index 000000000..bf11dee08 --- /dev/null +++ b/src/test/ui/parser/no-hex-float-literal.rs @@ -0,0 +1,9 @@ +fn main() { + 0xABC.Df; + //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields + 0x567.89; + //~^ ERROR hexadecimal float literal is not supported + 0xDEAD.BEEFp-2f; + //~^ ERROR invalid suffix `f` for float literal + //~| ERROR `{integer}` is a primitive type and therefore doesn't have fields +} diff --git a/src/test/ui/parser/no-hex-float-literal.stderr b/src/test/ui/parser/no-hex-float-literal.stderr new file mode 100644 index 000000000..258ab06d5 --- /dev/null +++ b/src/test/ui/parser/no-hex-float-literal.stderr @@ -0,0 +1,29 @@ +error: hexadecimal float literal is not supported + --> $DIR/no-hex-float-literal.rs:4:5 + | +LL | 0x567.89; + | ^^^^^^^^ + +error: invalid suffix `f` for float literal + --> $DIR/no-hex-float-literal.rs:6:18 + | +LL | 0xDEAD.BEEFp-2f; + | ^^ invalid suffix `f` + | + = help: valid suffixes are `f32` and `f64` + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/no-hex-float-literal.rs:2:11 + | +LL | 0xABC.Df; + | ^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/no-hex-float-literal.rs:6:12 + | +LL | 0xDEAD.BEEFp-2f; + | ^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/parser/no-unsafe-self.rs b/src/test/ui/parser/no-unsafe-self.rs new file mode 100644 index 000000000..d1cd8ad53 --- /dev/null +++ b/src/test/ui/parser/no-unsafe-self.rs @@ -0,0 +1,14 @@ +trait A { + fn foo(*mut self); //~ ERROR cannot pass `self` by raw pointer + fn baz(*const self); //~ ERROR cannot pass `self` by raw pointer + fn bar(*self); //~ ERROR cannot pass `self` by raw pointer +} + +struct X; +impl A for X { + fn foo(*mut self) { } //~ ERROR cannot pass `self` by raw pointer + fn baz(*const self) { } //~ ERROR cannot pass `self` by raw pointer + fn bar(*self) { } //~ ERROR cannot pass `self` by raw pointer +} + +fn main() { } diff --git a/src/test/ui/parser/no-unsafe-self.stderr b/src/test/ui/parser/no-unsafe-self.stderr new file mode 100644 index 000000000..23323945e --- /dev/null +++ b/src/test/ui/parser/no-unsafe-self.stderr @@ -0,0 +1,38 @@ +error: cannot pass `self` by raw pointer + --> $DIR/no-unsafe-self.rs:2:17 + | +LL | fn foo(*mut self); + | ^^^^ cannot pass `self` by raw pointer + +error: cannot pass `self` by raw pointer + --> $DIR/no-unsafe-self.rs:3:19 + | +LL | fn baz(*const self); + | ^^^^ cannot pass `self` by raw pointer + +error: cannot pass `self` by raw pointer + --> $DIR/no-unsafe-self.rs:4:13 + | +LL | fn bar(*self); + | ^^^^ cannot pass `self` by raw pointer + +error: cannot pass `self` by raw pointer + --> $DIR/no-unsafe-self.rs:9:17 + | +LL | fn foo(*mut self) { } + | ^^^^ cannot pass `self` by raw pointer + +error: cannot pass `self` by raw pointer + --> $DIR/no-unsafe-self.rs:10:19 + | +LL | fn baz(*const self) { } + | ^^^^ cannot pass `self` by raw pointer + +error: cannot pass `self` by raw pointer + --> $DIR/no-unsafe-self.rs:11:13 + | +LL | fn bar(*self) { } + | ^^^^ cannot pass `self` by raw pointer + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/not-a-pred.rs b/src/test/ui/parser/not-a-pred.rs new file mode 100644 index 000000000..5518b554d --- /dev/null +++ b/src/test/ui/parser/not-a-pred.rs @@ -0,0 +1,15 @@ +fn f(a: isize, b: isize) : lt(a, b) { } +//~^ ERROR return types are denoted using `->` +//~| ERROR expected type, found function `lt` [E0573] +//~| ERROR expected type, found local variable `a` [E0573] +//~| ERROR expected type, found local variable `b` [E0573] + +fn lt(a: isize, b: isize) { } + +fn main() { + let a: isize = 10; + let b: isize = 23; + check (lt(a, b)); + //~^ ERROR cannot find function `check` in this scope [E0425] + f(a, b); +} diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr new file mode 100644 index 000000000..bcc64a687 --- /dev/null +++ b/src/test/ui/parser/not-a-pred.stderr @@ -0,0 +1,34 @@ +error: return types are denoted using `->` + --> $DIR/not-a-pred.rs:1:26 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^ help: use `->` instead + +error[E0573]: expected type, found function `lt` + --> $DIR/not-a-pred.rs:1:28 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^^^^^^^^ not a type + +error[E0573]: expected type, found local variable `a` + --> $DIR/not-a-pred.rs:1:31 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^ not a type + +error[E0573]: expected type, found local variable `b` + --> $DIR/not-a-pred.rs:1:34 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^ not a type + +error[E0425]: cannot find function `check` in this scope + --> $DIR/not-a-pred.rs:12:5 + | +LL | check (lt(a, b)); + | ^^^^^ not found in this scope + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0425, E0573. +For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/nt-parsing-has-recovery.rs b/src/test/ui/parser/nt-parsing-has-recovery.rs new file mode 100644 index 000000000..ccbeb398a --- /dev/null +++ b/src/test/ui/parser/nt-parsing-has-recovery.rs @@ -0,0 +1,10 @@ +macro_rules! foo { + ($e:expr) => {} +} + +foo!(1 + @); //~ ERROR expected expression, found `@` +foo!(1 + @); //~ ERROR expected expression, found `@` + +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/nt-parsing-has-recovery.stderr b/src/test/ui/parser/nt-parsing-has-recovery.stderr new file mode 100644 index 000000000..263c4ad53 --- /dev/null +++ b/src/test/ui/parser/nt-parsing-has-recovery.stderr @@ -0,0 +1,29 @@ +error: expected expression, found `@` + --> $DIR/nt-parsing-has-recovery.rs:5:10 + | +LL | ($e:expr) => {} + | ------- while parsing argument for this `expr` macro fragment +... +LL | foo!(1 + @); + | ^ expected expression + +error: expected expression, found `@` + --> $DIR/nt-parsing-has-recovery.rs:6:10 + | +LL | ($e:expr) => {} + | ------- while parsing argument for this `expr` macro fragment +... +LL | foo!(1 + @); + | ^ expected expression + +error[E0308]: mismatched types + --> $DIR/nt-parsing-has-recovery.rs:9:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/numeric-lifetime.rs b/src/test/ui/parser/numeric-lifetime.rs new file mode 100644 index 000000000..2d82354c6 --- /dev/null +++ b/src/test/ui/parser/numeric-lifetime.rs @@ -0,0 +1,8 @@ +struct S<'1> { s: &'1 usize } +//~^ ERROR lifetimes cannot start with a number +//~| ERROR lifetimes cannot start with a number +fn main() { + // verify that the parse error doesn't stop type checking + let x: usize = ""; + //~^ ERROR mismatched types +} diff --git a/src/test/ui/parser/numeric-lifetime.stderr b/src/test/ui/parser/numeric-lifetime.stderr new file mode 100644 index 000000000..73a828952 --- /dev/null +++ b/src/test/ui/parser/numeric-lifetime.stderr @@ -0,0 +1,23 @@ +error: lifetimes cannot start with a number + --> $DIR/numeric-lifetime.rs:1:10 + | +LL | struct S<'1> { s: &'1 usize } + | ^^ + +error: lifetimes cannot start with a number + --> $DIR/numeric-lifetime.rs:1:20 + | +LL | struct S<'1> { s: &'1 usize } + | ^^ + +error[E0308]: mismatched types + --> $DIR/numeric-lifetime.rs:6:20 + | +LL | let x: usize = ""; + | ----- ^^ expected `usize`, found `&str` + | | + | expected due to this + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs new file mode 100644 index 000000000..e928f09aa --- /dev/null +++ b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs @@ -0,0 +1,9 @@ +trait Trait1 {} +trait Trait2 {} + +#[cfg(not_enabled)] +impl Trait1 for .. {} + +impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax + +fn main() {} diff --git a/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr new file mode 100644 index 000000000..b7108ced0 --- /dev/null +++ b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr @@ -0,0 +1,10 @@ +error: `impl Trait for .. {}` is an obsolete syntax + --> $DIR/obsolete-syntax-impl-for-dotdot.rs:7:1 + | +LL | impl Trait2 for .. {} + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `auto trait Trait {}` instead + +error: aborting due to previous error + diff --git a/src/test/ui/parser/old-suffixes-are-really-forbidden.rs b/src/test/ui/parser/old-suffixes-are-really-forbidden.rs new file mode 100644 index 000000000..eea95b7d6 --- /dev/null +++ b/src/test/ui/parser/old-suffixes-are-really-forbidden.rs @@ -0,0 +1,4 @@ +fn main() { + let a = 1_is; //~ ERROR invalid suffix + let b = 2_us; //~ ERROR invalid suffix +} diff --git a/src/test/ui/parser/old-suffixes-are-really-forbidden.stderr b/src/test/ui/parser/old-suffixes-are-really-forbidden.stderr new file mode 100644 index 000000000..fb309793b --- /dev/null +++ b/src/test/ui/parser/old-suffixes-are-really-forbidden.stderr @@ -0,0 +1,18 @@ +error: invalid suffix `is` for number literal + --> $DIR/old-suffixes-are-really-forbidden.rs:2:13 + | +LL | let a = 1_is; + | ^^^^ invalid suffix `is` + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +error: invalid suffix `us` for number literal + --> $DIR/old-suffixes-are-really-forbidden.rs:3:13 + | +LL | let b = 2_us; + | ^^^^ invalid suffix `us` + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.rs b/src/test/ui/parser/omitted-arg-in-item-fn.rs new file mode 100644 index 000000000..49cbc4d6b --- /dev/null +++ b/src/test/ui/parser/omitted-arg-in-item-fn.rs @@ -0,0 +1,4 @@ +fn foo(x) { //~ ERROR expected one of `:`, `@`, or `|`, found `)` +} + +fn main() {} diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.stderr b/src/test/ui/parser/omitted-arg-in-item-fn.stderr new file mode 100644 index 000000000..ce2eab051 --- /dev/null +++ b/src/test/ui/parser/omitted-arg-in-item-fn.stderr @@ -0,0 +1,22 @@ +error: expected one of `:`, `@`, or `|`, found `)` + --> $DIR/omitted-arg-in-item-fn.rs:1:9 + | +LL | fn foo(x) { + | ^ expected one of `:`, `@`, or `|` + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn foo(self: x) { + | +++++ +help: if this is a parameter name, give it a type + | +LL | fn foo(x: TypeName) { + | ++++++++++ +help: if this is a type, explicitly ignore the parameter name + | +LL | fn foo(_: x) { + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/operator-associativity.rs b/src/test/ui/parser/operator-associativity.rs new file mode 100644 index 000000000..4f40c80bc --- /dev/null +++ b/src/test/ui/parser/operator-associativity.rs @@ -0,0 +1,4 @@ +// run-pass +// Testcase for issue #130, operator associativity. + +pub fn main() { assert_eq!(3 * 5 / 2, 7); } diff --git a/src/test/ui/parser/paamayim-nekudotayim.rs b/src/test/ui/parser/paamayim-nekudotayim.rs new file mode 100644 index 000000000..cb151d652 --- /dev/null +++ b/src/test/ui/parser/paamayim-nekudotayim.rs @@ -0,0 +1,5 @@ +// http://phpsadness.com/sad/1 + +fn main() { + ::; //~ ERROR expected identifier, found `;` +} diff --git a/src/test/ui/parser/paamayim-nekudotayim.stderr b/src/test/ui/parser/paamayim-nekudotayim.stderr new file mode 100644 index 000000000..6ceba07f4 --- /dev/null +++ b/src/test/ui/parser/paamayim-nekudotayim.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `;` + --> $DIR/paamayim-nekudotayim.rs:4:7 + | +LL | ::; + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/parse-assoc-type-lt.rs b/src/test/ui/parser/parse-assoc-type-lt.rs new file mode 100644 index 000000000..d3fe6079a --- /dev/null +++ b/src/test/ui/parser/parse-assoc-type-lt.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + type T; + fn foo() -> Box<<Self as Foo>::T>; +} + +fn main() {} diff --git a/src/test/ui/parser/parse-error-correct.rs b/src/test/ui/parser/parse-error-correct.rs new file mode 100644 index 000000000..13759a235 --- /dev/null +++ b/src/test/ui/parser/parse-error-correct.rs @@ -0,0 +1,10 @@ +// Test that the parser is error correcting missing idents. Despite a parsing +// error (or two), we still run type checking (and don't get extra errors there). + +fn main() { + let y = 42; + let x = y.; //~ ERROR unexpected token + let x = y.(); //~ ERROR unexpected token + //~^ ERROR expected function, found `{integer}` + let x = y.foo; //~ ERROR `{integer}` is a primitive type and therefore doesn't have fields [E061 +} diff --git a/src/test/ui/parser/parse-error-correct.stderr b/src/test/ui/parser/parse-error-correct.stderr new file mode 100644 index 000000000..691df9126 --- /dev/null +++ b/src/test/ui/parser/parse-error-correct.stderr @@ -0,0 +1,33 @@ +error: unexpected token: `;` + --> $DIR/parse-error-correct.rs:6:15 + | +LL | let x = y.; + | ^ + +error: unexpected token: `(` + --> $DIR/parse-error-correct.rs:7:15 + | +LL | let x = y.(); + | ^ + +error[E0618]: expected function, found `{integer}` + --> $DIR/parse-error-correct.rs:7:13 + | +LL | let y = 42; + | - `y` has type `{integer}` +LL | let x = y.; +LL | let x = y.(); + | ^--- + | | + | call expression requires function + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/parse-error-correct.rs:9:15 + | +LL | let x = y.foo; + | ^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0610, E0618. +For more information about an error, try `rustc --explain E0610`. diff --git a/src/test/ui/parser/parse-panic.rs b/src/test/ui/parser/parse-panic.rs new file mode 100644 index 000000000..aeb2ba4fa --- /dev/null +++ b/src/test/ui/parser/parse-panic.rs @@ -0,0 +1,8 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unreachable_code)] + +fn dont_call_me() { panic!(); println!("{}", 1); } + +pub fn main() { } diff --git a/src/test/ui/parser/parser-recovery-1.rs b/src/test/ui/parser/parser-recovery-1.rs new file mode 100644 index 000000000..7e26b4f2b --- /dev/null +++ b/src/test/ui/parser/parser-recovery-1.rs @@ -0,0 +1,13 @@ +// Test that we can recover from missing braces in the parser. + +trait Foo { + fn bar() { + let x = foo(); + //~^ ERROR cannot find function `foo` in this scope +} + +fn main() { + let x = y.; + //~^ ERROR unexpected token + //~| ERROR cannot find value `y` in this scope +} //~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/parser-recovery-1.stderr b/src/test/ui/parser/parser-recovery-1.stderr new file mode 100644 index 000000000..f56060c3e --- /dev/null +++ b/src/test/ui/parser/parser-recovery-1.stderr @@ -0,0 +1,35 @@ +error: this file contains an unclosed delimiter + --> $DIR/parser-recovery-1.rs:13:54 + | +LL | trait Foo { + | - unclosed delimiter +LL | fn bar() { + | - this delimiter might not be properly closed... +... +LL | } + | - ...as it matches this but it has different indentation +... +LL | } + | ^ + +error: unexpected token: `;` + --> $DIR/parser-recovery-1.rs:10:15 + | +LL | let x = y.; + | ^ + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/parser-recovery-1.rs:5:17 + | +LL | let x = foo(); + | ^^^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/parser-recovery-1.rs:10:13 + | +LL | let x = y.; + | ^ not found in this scope + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/parser-recovery-2.rs b/src/test/ui/parser/parser-recovery-2.rs new file mode 100644 index 000000000..48b22afff --- /dev/null +++ b/src/test/ui/parser/parser-recovery-2.rs @@ -0,0 +1,12 @@ +// Test that we can recover from mismatched braces in the parser. + +trait Foo { + fn bar() { + let x = foo(); //~ ERROR cannot find function `foo` in this scope + ) //~ ERROR mismatched closing delimiter: `)` +} + +fn main() { + let x = y.; //~ ERROR unexpected token + //~^ ERROR cannot find value `y` in this scope +} diff --git a/src/test/ui/parser/parser-recovery-2.stderr b/src/test/ui/parser/parser-recovery-2.stderr new file mode 100644 index 000000000..0980d033f --- /dev/null +++ b/src/test/ui/parser/parser-recovery-2.stderr @@ -0,0 +1,30 @@ +error: unexpected token: `;` + --> $DIR/parser-recovery-2.rs:10:15 + | +LL | let x = y.; + | ^ + +error: mismatched closing delimiter: `)` + --> $DIR/parser-recovery-2.rs:4:14 + | +LL | fn bar() { + | ^ unclosed delimiter +LL | let x = foo(); +LL | ) + | ^ mismatched closing delimiter + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/parser-recovery-2.rs:5:17 + | +LL | let x = foo(); + | ^^^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/parser-recovery-2.rs:10:13 + | +LL | let x = y.; + | ^ not found in this scope + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/parser-unicode-whitespace.rs b/src/test/ui/parser/parser-unicode-whitespace.rs new file mode 100644 index 000000000..555cd68c3 --- /dev/null +++ b/src/test/ui/parser/parser-unicode-whitespace.rs @@ -0,0 +1,12 @@ +// run-pass +// Beware editing: it has numerous whitespace characters which are important. +// It contains one ranges from the 'PATTERN_WHITE_SPACE' property outlined in +// https://unicode.org/Public/UNIDATA/PropList.txt +// +// The characters in the first expression of the assertion can be generated +// from: "4\u{0C}+\n\t\r7\t*\u{20}2\u{85}/\u{200E}3\u{200F}*\u{2028}2\u{2029}" +pub fn main() { +assert_eq!(4+ + +7 * 2
/3*
2
, 4 + 7 * 2 / 3 * 2); +} diff --git a/src/test/ui/parser/pat-lt-bracket-1.rs b/src/test/ui/parser/pat-lt-bracket-1.rs new file mode 100644 index 000000000..2e2001434 --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-1.rs @@ -0,0 +1,7 @@ +fn main() { + match 42 { + x < 7 => (), + //~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<` + _ => () + } +} diff --git a/src/test/ui/parser/pat-lt-bracket-1.stderr b/src/test/ui/parser/pat-lt-bracket-1.stderr new file mode 100644 index 000000000..e8ccbad66 --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-1.stderr @@ -0,0 +1,8 @@ +error: expected one of `=>`, `@`, `if`, or `|`, found `<` + --> $DIR/pat-lt-bracket-1.rs:3:7 + | +LL | x < 7 => (), + | ^ expected one of `=>`, `@`, `if`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-lt-bracket-2.rs b/src/test/ui/parser/pat-lt-bracket-2.rs new file mode 100644 index 000000000..3a778ed14 --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-2.rs @@ -0,0 +1,4 @@ +fn a(B<) {} + //~^ error: expected one of `:`, `@`, or `|`, found `<` + +fn main() {} diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr new file mode 100644 index 000000000..c78f96e1a --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-2.stderr @@ -0,0 +1,18 @@ +error: expected one of `:`, `@`, or `|`, found `<` + --> $DIR/pat-lt-bracket-2.rs:1:7 + | +LL | fn a(B<) {} + | ^ expected one of `:`, `@`, or `|` + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn a(self: B<) {} + | +++++ +help: if this is a type, explicitly ignore the parameter name + | +LL | fn a(_: B<) {} + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-lt-bracket-3.rs b/src/test/ui/parser/pat-lt-bracket-3.rs new file mode 100644 index 000000000..a8bdfd3fa --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-3.rs @@ -0,0 +1,14 @@ +struct Foo<T>(T, T); + +impl<T> Foo<T> { + fn foo(&self) { + match *self { + Foo<T>(x, y) => { + //~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<` + println!("Goodbye, World!") + } + } + } +} + +fn main() {} diff --git a/src/test/ui/parser/pat-lt-bracket-3.stderr b/src/test/ui/parser/pat-lt-bracket-3.stderr new file mode 100644 index 000000000..bacf868e3 --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-3.stderr @@ -0,0 +1,8 @@ +error: expected one of `=>`, `@`, `if`, or `|`, found `<` + --> $DIR/pat-lt-bracket-3.rs:6:16 + | +LL | Foo<T>(x, y) => { + | ^ expected one of `=>`, `@`, `if`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-lt-bracket-4.rs b/src/test/ui/parser/pat-lt-bracket-4.rs new file mode 100644 index 000000000..de314f6c6 --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-4.rs @@ -0,0 +1,11 @@ +enum BtNode { + Node(u32,Box<BtNode>,Box<BtNode>), + Leaf(u32), +} + +fn main() { + let y = match 10 { + Foo<T>::A(value) => value, //~ error: expected one of `=>`, `@`, `if`, or `|`, found `<` + Foo<T>::B => 7, + }; +} diff --git a/src/test/ui/parser/pat-lt-bracket-4.stderr b/src/test/ui/parser/pat-lt-bracket-4.stderr new file mode 100644 index 000000000..911c276b9 --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-4.stderr @@ -0,0 +1,8 @@ +error: expected one of `=>`, `@`, `if`, or `|`, found `<` + --> $DIR/pat-lt-bracket-4.rs:8:12 + | +LL | Foo<T>::A(value) => value, + | ^ expected one of `=>`, `@`, `if`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-lt-bracket-5.rs b/src/test/ui/parser/pat-lt-bracket-5.rs new file mode 100644 index 000000000..aaece1f6b --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-5.rs @@ -0,0 +1,3 @@ +fn main() { + let v[0] = v[1]; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[` +} diff --git a/src/test/ui/parser/pat-lt-bracket-5.stderr b/src/test/ui/parser/pat-lt-bracket-5.stderr new file mode 100644 index 000000000..e23674bce --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-5.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` + --> $DIR/pat-lt-bracket-5.rs:2:10 + | +LL | let v[0] = v[1]; + | ^ expected one of `:`, `;`, `=`, `@`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs new file mode 100644 index 000000000..7becffa9f --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-6.rs @@ -0,0 +1,9 @@ +fn main() { + struct Test(&'static u8, [u8; 0]); + let x = Test(&0, []); + + let Test(&desc[..]) = x; + //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[` +} + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr new file mode 100644 index 000000000..035d0dbfe --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -0,0 +1,18 @@ +error: expected one of `)`, `,`, `@`, or `|`, found `[` + --> $DIR/pat-lt-bracket-6.rs:5:19 + | +LL | let Test(&desc[..]) = x; + | ^ + | | + | expected one of `)`, `,`, `@`, or `|` + | help: missing `,` + +error[E0308]: mismatched types + --> $DIR/pat-lt-bracket-6.rs:9:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected `()`, found integer + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs new file mode 100644 index 000000000..327aef5ad --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-7.rs @@ -0,0 +1,9 @@ +fn main() { + struct Thing(u8, [u8; 0]); + let foo = core::iter::empty(); + + for Thing(x[]) in foo {} + //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[` +} + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr new file mode 100644 index 000000000..004dcfb2a --- /dev/null +++ b/src/test/ui/parser/pat-lt-bracket-7.stderr @@ -0,0 +1,18 @@ +error: expected one of `)`, `,`, `@`, or `|`, found `[` + --> $DIR/pat-lt-bracket-7.rs:5:16 + | +LL | for Thing(x[]) in foo {} + | ^ + | | + | expected one of `)`, `,`, `@`, or `|` + | help: missing `,` + +error[E0308]: mismatched types + --> $DIR/pat-lt-bracket-7.rs:9:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected `()`, found integer + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-ranges-1.rs b/src/test/ui/parser/pat-ranges-1.rs new file mode 100644 index 000000000..1dafb5a07 --- /dev/null +++ b/src/test/ui/parser/pat-ranges-1.rs @@ -0,0 +1,5 @@ +// Parsing of range patterns + +fn main() { + let macropus!() ..= 11 = 12; //~ error: expected one of `:`, `;`, `=`, or `|`, found `..=` +} diff --git a/src/test/ui/parser/pat-ranges-1.stderr b/src/test/ui/parser/pat-ranges-1.stderr new file mode 100644 index 000000000..b64a3ce5c --- /dev/null +++ b/src/test/ui/parser/pat-ranges-1.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, or `|`, found `..=` + --> $DIR/pat-ranges-1.rs:4:21 + | +LL | let macropus!() ..= 11 = 12; + | ^^^ expected one of `:`, `;`, `=`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-ranges-2.rs b/src/test/ui/parser/pat-ranges-2.rs new file mode 100644 index 000000000..1593222ac --- /dev/null +++ b/src/test/ui/parser/pat-ranges-2.rs @@ -0,0 +1,5 @@ +// Parsing of range patterns + +fn main() { + let 10 ..= makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!` +} diff --git a/src/test/ui/parser/pat-ranges-2.stderr b/src/test/ui/parser/pat-ranges-2.stderr new file mode 100644 index 000000000..1a9e33beb --- /dev/null +++ b/src/test/ui/parser/pat-ranges-2.stderr @@ -0,0 +1,8 @@ +error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!` + --> $DIR/pat-ranges-2.rs:4:26 + | +LL | let 10 ..= makropulos!() = 12; + | ^ expected one of `::`, `:`, `;`, `=`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-ranges-3.rs b/src/test/ui/parser/pat-ranges-3.rs new file mode 100644 index 000000000..8976dcf0d --- /dev/null +++ b/src/test/ui/parser/pat-ranges-3.rs @@ -0,0 +1,5 @@ +// Parsing of range patterns + +fn main() { + let 10 ..= 10 + 3 = 12; //~ expected one of `:`, `;`, `=`, or `|`, found `+` +} diff --git a/src/test/ui/parser/pat-ranges-3.stderr b/src/test/ui/parser/pat-ranges-3.stderr new file mode 100644 index 000000000..c9787b789 --- /dev/null +++ b/src/test/ui/parser/pat-ranges-3.stderr @@ -0,0 +1,8 @@ +error: expected one of `:`, `;`, `=`, or `|`, found `+` + --> $DIR/pat-ranges-3.rs:4:19 + | +LL | let 10 ..= 10 + 3 = 12; + | ^ expected one of `:`, `;`, `=`, or `|` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-ranges-4.rs b/src/test/ui/parser/pat-ranges-4.rs new file mode 100644 index 000000000..61188976b --- /dev/null +++ b/src/test/ui/parser/pat-ranges-4.rs @@ -0,0 +1,6 @@ +// Parsing of range patterns + +fn main() { + let 10 - 3 ..= 10 = 8; + //~^ error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-` +} diff --git a/src/test/ui/parser/pat-ranges-4.stderr b/src/test/ui/parser/pat-ranges-4.stderr new file mode 100644 index 000000000..69084b5a4 --- /dev/null +++ b/src/test/ui/parser/pat-ranges-4.stderr @@ -0,0 +1,8 @@ +error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-` + --> $DIR/pat-ranges-4.rs:4:12 + | +LL | let 10 - 3 ..= 10 = 8; + | ^ expected one of 7 possible tokens + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-ref-enum.rs b/src/test/ui/parser/pat-ref-enum.rs new file mode 100644 index 000000000..412dd141d --- /dev/null +++ b/src/test/ui/parser/pat-ref-enum.rs @@ -0,0 +1,8 @@ +fn matcher(x: Option<isize>) { + match x { + ref Some(i) => {} //~ ERROR expected identifier, found enum pattern + None => {} + } +} + +fn main() {} diff --git a/src/test/ui/parser/pat-ref-enum.stderr b/src/test/ui/parser/pat-ref-enum.stderr new file mode 100644 index 000000000..a3bce3372 --- /dev/null +++ b/src/test/ui/parser/pat-ref-enum.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found enum pattern + --> $DIR/pat-ref-enum.rs:3:11 + | +LL | ref Some(i) => {} + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-tuple-1.rs b/src/test/ui/parser/pat-tuple-1.rs new file mode 100644 index 000000000..0e49b547f --- /dev/null +++ b/src/test/ui/parser/pat-tuple-1.rs @@ -0,0 +1,5 @@ +fn main() { + match (0, 1) { + (, ..) => {} //~ ERROR expected pattern, found `,` + } +} diff --git a/src/test/ui/parser/pat-tuple-1.stderr b/src/test/ui/parser/pat-tuple-1.stderr new file mode 100644 index 000000000..391f2c428 --- /dev/null +++ b/src/test/ui/parser/pat-tuple-1.stderr @@ -0,0 +1,8 @@ +error: expected pattern, found `,` + --> $DIR/pat-tuple-1.rs:3:10 + | +LL | (, ..) => {} + | ^ expected pattern + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs new file mode 100644 index 000000000..a8f3debd3 --- /dev/null +++ b/src/test/ui/parser/pat-tuple-2.rs @@ -0,0 +1,7 @@ +// check-pass + +fn main() { + match (0, 1, 2) { + (pat, ..,) => {} + } +} diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs new file mode 100644 index 000000000..1486ab231 --- /dev/null +++ b/src/test/ui/parser/pat-tuple-3.rs @@ -0,0 +1,6 @@ +fn main() { + match (0, 1, 2) { + (.., pat, ..) => {} + //~^ ERROR `..` can only be used once per tuple pattern + } +} diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr new file mode 100644 index 000000000..9ac0611c5 --- /dev/null +++ b/src/test/ui/parser/pat-tuple-3.stderr @@ -0,0 +1,10 @@ +error: `..` can only be used once per tuple pattern + --> $DIR/pat-tuple-3.rs:3:19 + | +LL | (.., pat, ..) => {} + | -- ^^ can only be used once per tuple pattern + | | + | previously used here + +error: aborting due to previous error + diff --git a/src/test/ui/parser/pub-method-macro.rs b/src/test/ui/parser/pub-method-macro.rs new file mode 100644 index 000000000..0183bdcf6 --- /dev/null +++ b/src/test/ui/parser/pub-method-macro.rs @@ -0,0 +1,23 @@ +// Issue #18317 + +mod bleh { + macro_rules! defn { + ($n:ident) => ( + fn $n (&self) -> i32 { + println!("{}", stringify!($n)); + 1 + } + ) + } + + #[derive(Copy, Clone)] + pub struct S; + + impl S { + pub defn!(f); //~ ERROR can't qualify macro invocation with `pub` + //~^ HELP remove the visibility + //~| HELP try adjusting the macro to put `pub` inside the invocation + } +} + +fn main() {} diff --git a/src/test/ui/parser/pub-method-macro.stderr b/src/test/ui/parser/pub-method-macro.stderr new file mode 100644 index 000000000..7c7a90926 --- /dev/null +++ b/src/test/ui/parser/pub-method-macro.stderr @@ -0,0 +1,10 @@ +error: can't qualify macro invocation with `pub` + --> $DIR/pub-method-macro.rs:17:9 + | +LL | pub defn!(f); + | ^^^ help: remove the visibility + | + = help: try adjusting the macro to put `pub` inside the invocation + +error: aborting due to previous error + diff --git a/src/test/ui/parser/public-instead-of-pub.fixed b/src/test/ui/parser/public-instead-of-pub.fixed new file mode 100644 index 000000000..01db60999 --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub.fixed @@ -0,0 +1,8 @@ +// Checks what happens when `public` is used instead of the correct, `pub` +// edition:2018 +// run-rustfix +pub struct X; +//~^ ERROR expected one of `!` or `::`, found keyword `struct` +//~^^ HELP write `pub` instead of `public` to make the item public + +fn main() {} diff --git a/src/test/ui/parser/public-instead-of-pub.rs b/src/test/ui/parser/public-instead-of-pub.rs new file mode 100644 index 000000000..18e0fd3af --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub.rs @@ -0,0 +1,8 @@ +// Checks what happens when `public` is used instead of the correct, `pub` +// edition:2018 +// run-rustfix +public struct X; +//~^ ERROR expected one of `!` or `::`, found keyword `struct` +//~^^ HELP write `pub` instead of `public` to make the item public + +fn main() {} diff --git a/src/test/ui/parser/public-instead-of-pub.stderr b/src/test/ui/parser/public-instead-of-pub.stderr new file mode 100644 index 000000000..af875491e --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub.stderr @@ -0,0 +1,13 @@ +error: expected one of `!` or `::`, found keyword `struct` + --> $DIR/public-instead-of-pub.rs:4:8 + | +LL | public struct X; + | ^^^^^^ expected one of `!` or `::` + | +help: write `pub` instead of `public` to make the item public + | +LL | pub struct X; + | ~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/qualified-path-in-turbofish.fixed b/src/test/ui/parser/qualified-path-in-turbofish.fixed new file mode 100644 index 000000000..404d2f776 --- /dev/null +++ b/src/test/ui/parser/qualified-path-in-turbofish.fixed @@ -0,0 +1,19 @@ +// run-rustfix +trait T { + type Ty; +} + +struct Impl; + +impl T for Impl { + type Ty = u32; +} + +fn template<T>() -> i64 { + 3 +} + +fn main() { + template::<<Impl as T>::Ty>(); + //~^ ERROR found single colon before projection in qualified path +} diff --git a/src/test/ui/parser/qualified-path-in-turbofish.rs b/src/test/ui/parser/qualified-path-in-turbofish.rs new file mode 100644 index 000000000..2f4b2ed34 --- /dev/null +++ b/src/test/ui/parser/qualified-path-in-turbofish.rs @@ -0,0 +1,19 @@ +// run-rustfix +trait T { + type Ty; +} + +struct Impl; + +impl T for Impl { + type Ty = u32; +} + +fn template<T>() -> i64 { + 3 +} + +fn main() { + template::<<Impl as T>:Ty>(); + //~^ ERROR found single colon before projection in qualified path +} diff --git a/src/test/ui/parser/qualified-path-in-turbofish.stderr b/src/test/ui/parser/qualified-path-in-turbofish.stderr new file mode 100644 index 000000000..8857d2ef3 --- /dev/null +++ b/src/test/ui/parser/qualified-path-in-turbofish.stderr @@ -0,0 +1,8 @@ +error: found single colon before projection in qualified path + --> $DIR/qualified-path-in-turbofish.rs:17:27 + | +LL | template::<<Impl as T>:Ty>(); + | ^ help: use double colon: `::` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/range-3.rs b/src/test/ui/parser/range-3.rs new file mode 100644 index 000000000..2c917a24e --- /dev/null +++ b/src/test/ui/parser/range-3.rs @@ -0,0 +1,6 @@ +// Test range syntax - syntax errors. + +pub fn main() { + let r = 1..2..3; + //~^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `..` +} diff --git a/src/test/ui/parser/range-3.stderr b/src/test/ui/parser/range-3.stderr new file mode 100644 index 000000000..340167f18 --- /dev/null +++ b/src/test/ui/parser/range-3.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `..` + --> $DIR/range-3.rs:4:17 + | +LL | let r = 1..2..3; + | ^^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: aborting due to previous error + diff --git a/src/test/ui/parser/range-4.rs b/src/test/ui/parser/range-4.rs new file mode 100644 index 000000000..c970c96de --- /dev/null +++ b/src/test/ui/parser/range-4.rs @@ -0,0 +1,6 @@ +// Test range syntax - syntax errors. + +pub fn main() { + let r = ..1..2; + //~^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `..` +} diff --git a/src/test/ui/parser/range-4.stderr b/src/test/ui/parser/range-4.stderr new file mode 100644 index 000000000..720d48938 --- /dev/null +++ b/src/test/ui/parser/range-4.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `..` + --> $DIR/range-4.rs:4:16 + | +LL | let r = ..1..2; + | ^^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: aborting due to previous error + diff --git a/src/test/ui/parser/range-inclusive-extra-equals.rs b/src/test/ui/parser/range-inclusive-extra-equals.rs new file mode 100644 index 000000000..d41c0699c --- /dev/null +++ b/src/test/ui/parser/range-inclusive-extra-equals.rs @@ -0,0 +1,10 @@ +// Makes sure that a helpful message is shown when someone mistypes +// an inclusive range as `..==` rather than `..=`. This is an +// easy mistake, because of the resemblance to`==`. +// See #86395 for a bit of background. + +pub fn main() { + if let 1..==3 = 1 {} //~ERROR unexpected `=` after inclusive range + //~|HELP use `..=` instead + //~|NOTE inclusive ranges end with a single equals sign +} diff --git a/src/test/ui/parser/range-inclusive-extra-equals.stderr b/src/test/ui/parser/range-inclusive-extra-equals.stderr new file mode 100644 index 000000000..d37b6be4f --- /dev/null +++ b/src/test/ui/parser/range-inclusive-extra-equals.stderr @@ -0,0 +1,10 @@ +error: unexpected `=` after inclusive range + --> $DIR/range-inclusive-extra-equals.rs:7:13 + | +LL | if let 1..==3 = 1 {} + | ^^^^ help: use `..=` instead + | + = note: inclusive ranges end with a single equals sign (`..=`) + +error: aborting due to previous error + diff --git a/src/test/ui/parser/range_inclusive.fixed b/src/test/ui/parser/range_inclusive.fixed new file mode 100644 index 000000000..fe23880d1 --- /dev/null +++ b/src/test/ui/parser/range_inclusive.fixed @@ -0,0 +1,7 @@ +// run-rustfix +// Make sure that inclusive ranges with no end point don't parse. + +pub fn main() { + for _ in 1.. {} //~ERROR inclusive range with no end + //~^HELP use `..` instead +} diff --git a/src/test/ui/parser/range_inclusive.rs b/src/test/ui/parser/range_inclusive.rs new file mode 100644 index 000000000..bc6d2413d --- /dev/null +++ b/src/test/ui/parser/range_inclusive.rs @@ -0,0 +1,7 @@ +// run-rustfix +// Make sure that inclusive ranges with no end point don't parse. + +pub fn main() { + for _ in 1..= {} //~ERROR inclusive range with no end + //~^HELP use `..` instead +} diff --git a/src/test/ui/parser/range_inclusive.stderr b/src/test/ui/parser/range_inclusive.stderr new file mode 100644 index 000000000..8a9178263 --- /dev/null +++ b/src/test/ui/parser/range_inclusive.stderr @@ -0,0 +1,11 @@ +error[E0586]: inclusive range with no end + --> $DIR/range_inclusive.rs:5:15 + | +LL | for _ in 1..= {} + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/parser/range_inclusive_dotdotdot.rs b/src/test/ui/parser/range_inclusive_dotdotdot.rs new file mode 100644 index 000000000..c3e600e77 --- /dev/null +++ b/src/test/ui/parser/range_inclusive_dotdotdot.rs @@ -0,0 +1,23 @@ +// Make sure that inclusive ranges with `...` syntax don't parse. + +use std::ops::RangeToInclusive; + +fn return_range_to() -> RangeToInclusive<i32> { + return ...1; //~ERROR unexpected token: `...` + //~^HELP use `..` for an exclusive range + //~^^HELP or `..=` for an inclusive range +} + +pub fn main() { + let x = ...0; //~ERROR unexpected token: `...` + //~^HELP use `..` for an exclusive range + //~^^HELP or `..=` for an inclusive range + + let x = 5...5; //~ERROR unexpected token: `...` + //~^HELP use `..` for an exclusive range + //~^^HELP or `..=` for an inclusive range + + for _ in 0...1 {} //~ERROR unexpected token: `...` + //~^HELP use `..` for an exclusive range + //~^^HELP or `..=` for an inclusive range +} diff --git a/src/test/ui/parser/range_inclusive_dotdotdot.stderr b/src/test/ui/parser/range_inclusive_dotdotdot.stderr new file mode 100644 index 000000000..2dc2c87eb --- /dev/null +++ b/src/test/ui/parser/range_inclusive_dotdotdot.stderr @@ -0,0 +1,62 @@ +error: unexpected token: `...` + --> $DIR/range_inclusive_dotdotdot.rs:6:12 + | +LL | return ...1; + | ^^^ + | +help: use `..` for an exclusive range + | +LL | return ..1; + | ~~ +help: or `..=` for an inclusive range + | +LL | return ..=1; + | ~~~ + +error: unexpected token: `...` + --> $DIR/range_inclusive_dotdotdot.rs:12:13 + | +LL | let x = ...0; + | ^^^ + | +help: use `..` for an exclusive range + | +LL | let x = ..0; + | ~~ +help: or `..=` for an inclusive range + | +LL | let x = ..=0; + | ~~~ + +error: unexpected token: `...` + --> $DIR/range_inclusive_dotdotdot.rs:16:14 + | +LL | let x = 5...5; + | ^^^ + | +help: use `..` for an exclusive range + | +LL | let x = 5..5; + | ~~ +help: or `..=` for an inclusive range + | +LL | let x = 5..=5; + | ~~~ + +error: unexpected token: `...` + --> $DIR/range_inclusive_dotdotdot.rs:20:15 + | +LL | for _ in 0...1 {} + | ^^^ + | +help: use `..` for an exclusive range + | +LL | for _ in 0..1 {} + | ~~ +help: or `..=` for an inclusive range + | +LL | for _ in 0..=1 {} + | ~~~ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/ranges-precedence.rs b/src/test/ui/parser/ranges-precedence.rs new file mode 100644 index 000000000..db241ed0c --- /dev/null +++ b/src/test/ui/parser/ranges-precedence.rs @@ -0,0 +1,52 @@ +// run-pass +// Test that the precedence of ranges is correct + + + +struct Foo { + foo: usize, +} + +impl Foo { + fn bar(&self) -> usize { 5 } +} + +fn main() { + let x = 1+3..4+5; + assert_eq!(x, (4..9)); + + let x = 1..4+5; + assert_eq!(x, (1..9)); + + let x = 1+3..4; + assert_eq!(x, (4..4)); + + let a = Foo { foo: 3 }; + let x = a.foo..a.bar(); + assert_eq!(x, (3..5)); + + let x = 1+3..; + assert_eq!(x, (4..)); + let x = ..1+3; + assert_eq!(x, (..4)); + + let a = &[0, 1, 2, 3, 4, 5, 6]; + let x = &a[1+1..2+2]; + assert_eq!(x, &a[2..4]); + let x = &a[..1+2]; + assert_eq!(x, &a[..3]); + let x = &a[1+2..]; + assert_eq!(x, &a[3..]); + + for _i in 2+4..10-3 {} + + let i = 42; + for _ in 1..i {} + for _ in 1.. { break; } + + let x = [1]..[2]; + assert_eq!(x, (([1])..([2]))); + + let y = ..; + assert_eq!(y, (..)); +} diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs new file mode 100644 index 000000000..bdfc29a3d --- /dev/null +++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs @@ -0,0 +1,5 @@ +// This won't actually panic because of the error comment -- the `"` needs to be +// the last byte in the file (including not having a trailing newline) +// Prior to the fix you get the error: 'expected item, found `r" ...`' +// because the string being unterminated wasn't properly detected. +r" //~ unterminated raw string diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr new file mode 100644 index 000000000..3a7e2a4b1 --- /dev/null +++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr @@ -0,0 +1,9 @@ +error[E0748]: unterminated raw string + --> $DIR/issue-70677-panic-on-unterminated-raw-str-at-eof.rs:5:1 + | +LL | r" + | ^ unterminated raw string + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/test/ui/parser/raw/raw-byte-string-eof.rs b/src/test/ui/parser/raw/raw-byte-string-eof.rs new file mode 100644 index 000000000..b74907b72 --- /dev/null +++ b/src/test/ui/parser/raw/raw-byte-string-eof.rs @@ -0,0 +1,3 @@ +pub fn main() { + br##"a"#; //~ unterminated raw string +} diff --git a/src/test/ui/parser/raw/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr new file mode 100644 index 000000000..a76668e80 --- /dev/null +++ b/src/test/ui/parser/raw/raw-byte-string-eof.stderr @@ -0,0 +1,13 @@ +error[E0748]: unterminated raw string + --> $DIR/raw-byte-string-eof.rs:2:5 + | +LL | br##"a"#; + | ^ - help: consider terminating the string here: `##` + | | + | unterminated raw string + | + = note: this raw string should be terminated with `"##` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs new file mode 100644 index 000000000..163c8ac66 --- /dev/null +++ b/src/test/ui/parser/raw/raw-byte-string-literals.rs @@ -0,0 +1,7 @@ +// ignore-tidy-cr + +pub fn main() { + br"a
"; //~ ERROR bare CR not allowed in raw string + br"é"; //~ ERROR raw byte string must be ASCII + br##~"a"~##; //~ ERROR only `#` is allowed in raw string delimitation +} diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr new file mode 100644 index 000000000..cfc877104 --- /dev/null +++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr @@ -0,0 +1,20 @@ +error: bare CR not allowed in raw string + --> $DIR/raw-byte-string-literals.rs:4:9 + | +LL | br"a
"; + | ^ + +error: raw byte string must be ASCII + --> $DIR/raw-byte-string-literals.rs:5:8 + | +LL | br"é"; + | ^ must be ASCII + +error: found invalid character; only `#` is allowed in raw string delimitation: ~ + --> $DIR/raw-byte-string-literals.rs:6:5 + | +LL | br##~"a"~##; + | ^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/raw/raw-literal-keywords.rs b/src/test/ui/parser/raw/raw-literal-keywords.rs new file mode 100644 index 000000000..a986980fa --- /dev/null +++ b/src/test/ui/parser/raw/raw-literal-keywords.rs @@ -0,0 +1,25 @@ +fn test_if() { + r#if true { } //~ ERROR found keyword `true` +} + +fn test_struct() { + r#struct Test; //~ ERROR found `Test` +} + +fn test_union() { + r#union Test; //~ ERROR found `Test` +} + +fn test_if_2() { + let _ = r#if; //~ ERROR cannot find value `r#if` in this scope +} + +fn test_struct_2() { + let _ = r#struct; //~ ERROR cannot find value `r#struct` in this scope +} + +fn test_union_2() { + let _ = r#union; //~ ERROR cannot find value `union` in this scope +} + +fn main() {} diff --git a/src/test/ui/parser/raw/raw-literal-keywords.stderr b/src/test/ui/parser/raw/raw-literal-keywords.stderr new file mode 100644 index 000000000..f7b6c894a --- /dev/null +++ b/src/test/ui/parser/raw/raw-literal-keywords.stderr @@ -0,0 +1,39 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found keyword `true` + --> $DIR/raw-literal-keywords.rs:2:10 + | +LL | r#if true { } + | ^^^^ expected one of 8 possible tokens + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` + --> $DIR/raw-literal-keywords.rs:6:14 + | +LL | r#struct Test; + | ^^^^ expected one of 8 possible tokens + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` + --> $DIR/raw-literal-keywords.rs:10:13 + | +LL | r#union Test; + | ^^^^ expected one of 8 possible tokens + +error[E0425]: cannot find value `r#if` in this scope + --> $DIR/raw-literal-keywords.rs:14:13 + | +LL | let _ = r#if; + | ^^^^ not found in this scope + +error[E0425]: cannot find value `r#struct` in this scope + --> $DIR/raw-literal-keywords.rs:18:13 + | +LL | let _ = r#struct; + | ^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `union` in this scope + --> $DIR/raw-literal-keywords.rs:22:13 + | +LL | let _ = r#union; + | ^^^^^^^ not found in this scope + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/raw/raw-literal-self.rs b/src/test/ui/parser/raw/raw-literal-self.rs new file mode 100644 index 000000000..a0c9e24c2 --- /dev/null +++ b/src/test/ui/parser/raw/raw-literal-self.rs @@ -0,0 +1,4 @@ +fn main() { + let r#self: (); + //~^ ERROR `self` cannot be a raw identifier +} diff --git a/src/test/ui/parser/raw/raw-literal-self.stderr b/src/test/ui/parser/raw/raw-literal-self.stderr new file mode 100644 index 000000000..2a40dfe20 --- /dev/null +++ b/src/test/ui/parser/raw/raw-literal-self.stderr @@ -0,0 +1,8 @@ +error: `self` cannot be a raw identifier + --> $DIR/raw-literal-self.rs:2:9 + | +LL | let r#self: (); + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/raw/raw-literal-underscore.rs b/src/test/ui/parser/raw/raw-literal-underscore.rs new file mode 100644 index 000000000..a9d9e13a9 --- /dev/null +++ b/src/test/ui/parser/raw/raw-literal-underscore.rs @@ -0,0 +1,4 @@ +fn main() { + let r#_: (); + //~^ ERROR `_` cannot be a raw identifier +} diff --git a/src/test/ui/parser/raw/raw-literal-underscore.stderr b/src/test/ui/parser/raw/raw-literal-underscore.stderr new file mode 100644 index 000000000..d7a364d85 --- /dev/null +++ b/src/test/ui/parser/raw/raw-literal-underscore.stderr @@ -0,0 +1,8 @@ +error: `_` cannot be a raw identifier + --> $DIR/raw-literal-underscore.rs:2:9 + | +LL | let r#_: (); + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/raw/raw-str-delim.rs b/src/test/ui/parser/raw/raw-str-delim.rs new file mode 100644 index 000000000..2f13893ce --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-delim.rs @@ -0,0 +1,3 @@ +static s: &'static str = + r#~"#"~# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation +; diff --git a/src/test/ui/parser/raw/raw-str-delim.stderr b/src/test/ui/parser/raw/raw-str-delim.stderr new file mode 100644 index 000000000..8a04f99a1 --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-delim.stderr @@ -0,0 +1,8 @@ +error: found invalid character; only `#` is allowed in raw string delimitation: ~ + --> $DIR/raw-str-delim.rs:2:5 + | +LL | r#~"#"~# + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/raw/raw-str-in-macro-call.rs b/src/test/ui/parser/raw/raw-str-in-macro-call.rs new file mode 100644 index 000000000..462c2279f --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-in-macro-call.rs @@ -0,0 +1,14 @@ +// check-pass + +macro_rules! m1 { + ($tt:tt #) => () +} + +macro_rules! m2 { + ($tt:tt) => () +} + +fn main() { + m1!(r#"abc"##); + m2!(r#"abc"#); +} diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs new file mode 100644 index 000000000..38537f8b3 --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-unbalanced.rs @@ -0,0 +1,22 @@ +static s: &'static str = + r#""## //~ ERROR too many `#` when terminating raw string +; + +static s2: &'static str = + r#" + "#### //~ ERROR too many `#` when terminating raw string +; + +const A: &'static str = r"" //~ ERROR expected `;`, found `#` + +// Test +#[test] +fn test() {} + +const B: &'static str = r""## //~ ERROR too many `#` when terminating raw string + +// Test +#[test] +fn test2() {} + +fn main() {} diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr new file mode 100644 index 000000000..eac8c06c1 --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr @@ -0,0 +1,36 @@ +error: too many `#` when terminating raw string + --> $DIR/raw-str-unbalanced.rs:2:10 + | +LL | r#""## + | -----^ help: remove the extra `#` + | | + | this raw string started with 1 `#` + +error: too many `#` when terminating raw string + --> $DIR/raw-str-unbalanced.rs:7:9 + | +LL | / r#" +LL | | "#### + | | -^^^ help: remove the extra `#`s + | |________| + | this raw string started with 1 `#` + +error: expected `;`, found `#` + --> $DIR/raw-str-unbalanced.rs:10:28 + | +LL | const A: &'static str = r"" + | ^ help: add `;` here +... +LL | #[test] + | - unexpected token + +error: too many `#` when terminating raw string + --> $DIR/raw-str-unbalanced.rs:16:28 + | +LL | const B: &'static str = r""## + | ---^^ help: remove the extra `#`s + | | + | this raw string started with 0 `#`s + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/raw/raw-str-unterminated.rs b/src/test/ui/parser/raw/raw-str-unterminated.rs new file mode 100644 index 000000000..fd3172955 --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-unterminated.rs @@ -0,0 +1,4 @@ +static s: &'static str = + r#" string literal goes on + and on + //~^^ ERROR unterminated raw string diff --git a/src/test/ui/parser/raw/raw-str-unterminated.stderr b/src/test/ui/parser/raw/raw-str-unterminated.stderr new file mode 100644 index 000000000..077f763f1 --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-unterminated.stderr @@ -0,0 +1,11 @@ +error[E0748]: unterminated raw string + --> $DIR/raw-str-unterminated.rs:2:5 + | +LL | r#" string literal goes on + | ^ unterminated raw string + | + = note: this raw string should be terminated with `"#` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/test/ui/parser/raw/raw-string-2.rs b/src/test/ui/parser/raw/raw-string-2.rs new file mode 100644 index 000000000..067332d28 --- /dev/null +++ b/src/test/ui/parser/raw/raw-string-2.rs @@ -0,0 +1,4 @@ +fn main() { + let x = r###"here's a long string"# "# "##; + //~^ ERROR unterminated raw string +} diff --git a/src/test/ui/parser/raw/raw-string-2.stderr b/src/test/ui/parser/raw/raw-string-2.stderr new file mode 100644 index 000000000..8bbac9d7b --- /dev/null +++ b/src/test/ui/parser/raw/raw-string-2.stderr @@ -0,0 +1,11 @@ +error[E0748]: unterminated raw string + --> $DIR/raw-string-2.rs:2:13 + | +LL | let x = r###"here's a long string"# "# "##; + | ^ unterminated raw string -- help: consider terminating the string here: `###` + | + = note: this raw string should be terminated with `"###` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/test/ui/parser/raw/raw-string.rs b/src/test/ui/parser/raw/raw-string.rs new file mode 100644 index 000000000..84f07c4a9 --- /dev/null +++ b/src/test/ui/parser/raw/raw-string.rs @@ -0,0 +1,4 @@ +fn main() { + let x = r##"lol"#; + //~^ ERROR unterminated raw string +} diff --git a/src/test/ui/parser/raw/raw-string.stderr b/src/test/ui/parser/raw/raw-string.stderr new file mode 100644 index 000000000..b2b853a89 --- /dev/null +++ b/src/test/ui/parser/raw/raw-string.stderr @@ -0,0 +1,13 @@ +error[E0748]: unterminated raw string + --> $DIR/raw-string.rs:2:13 + | +LL | let x = r##"lol"#; + | ^ - help: consider terminating the string here: `##` + | | + | unterminated raw string + | + = note: this raw string should be terminated with `"##` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/test/ui/parser/recover-assoc-const-constraint.rs b/src/test/ui/parser/recover-assoc-const-constraint.rs new file mode 100644 index 000000000..1453e6cb5 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-assoc-const-constraint.stderr b/src/test/ui/parser/recover-assoc-const-constraint.stderr new file mode 100644 index 000000000..2d36ce4e9 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-assoc-eq-missing-term.rs b/src/test/ui/parser/recover-assoc-eq-missing-term.rs new file mode 100644 index 000000000..4b42c44dc --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-assoc-eq-missing-term.stderr b/src/test/ui/parser/recover-assoc-eq-missing-term.stderr new file mode 100644 index 000000000..152f7f2fb --- /dev/null +++ b/src/test/ui/parser/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 previous error + diff --git a/src/test/ui/parser/recover-assoc-lifetime-constraint.rs b/src/test/ui/parser/recover-assoc-lifetime-constraint.rs new file mode 100644 index 000000000..558fcdfe1 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-assoc-lifetime-constraint.stderr b/src/test/ui/parser/recover-assoc-lifetime-constraint.stderr new file mode 100644 index 000000000..79437533d --- /dev/null +++ b/src/test/ui/parser/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 previous error + diff --git a/src/test/ui/parser/recover-const-async-fn-ptr.rs b/src/test/ui/parser/recover-const-async-fn-ptr.rs new file mode 100644 index 000000000..25af8772c --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-const-async-fn-ptr.stderr b/src/test/ui/parser/recover-const-async-fn-ptr.stderr new file mode 100644 index 000000000..7012096b6 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-enum.rs b/src/test/ui/parser/recover-enum.rs new file mode 100644 index 000000000..08dd939e2 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-enum.stderr b/src/test/ui/parser/recover-enum.stderr new file mode 100644 index 000000000..a2b650e4f --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-enum2.rs b/src/test/ui/parser/recover-enum2.rs new file mode 100644 index 000000000..0c9420889 --- /dev/null +++ b/src/test/ui/parser/recover-enum2.rs @@ -0,0 +1,28 @@ +fn main() { + enum Test { + Var1, + Var2(String), + Var3 { + abc: {}, //~ ERROR: expected type, found `{` + }, + } + + // recover... + let a = 1; + enum Test2 { + Fine, + } + + enum Test3 { + StillFine { + def: i32, + }, + } + + { + // fail again + enum Test4 { + Nope(i32 {}) //~ ERROR: found `{` + } + } +} diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr new file mode 100644 index 000000000..ee29f0663 --- /dev/null +++ b/src/test/ui/parser/recover-enum2.stderr @@ -0,0 +1,14 @@ +error: expected type, found `{` + --> $DIR/recover-enum2.rs:6:18 + | +LL | abc: {}, + | ^ expected type + +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{` + --> $DIR/recover-enum2.rs:25:22 + | +LL | Nope(i32 {}) + | ^ expected one of 7 possible tokens + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs new file mode 100644 index 000000000..e815c7611 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr new file mode 100644 index 000000000..17237c930 --- /dev/null +++ b/src/test/ui/parser/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 previous error + diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets.rs b/src/test/ui/parser/recover-field-extra-angle-brackets.rs new file mode 100644 index 000000000..5e0e00bcb --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-field-extra-angle-brackets.stderr b/src/test/ui/parser/recover-field-extra-angle-brackets.stderr new file mode 100644 index 000000000..318e55f6e --- /dev/null +++ b/src/test/ui/parser/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 previous error + diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.rs b/src/test/ui/parser/recover-for-loop-parens-around-head.rs new file mode 100644 index 000000000..053b428bd --- /dev/null +++ b/src/test/ui/parser/recover-for-loop-parens-around-head.rs @@ -0,0 +1,15 @@ +// 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 expected one of `)`, `,`, `@`, or `|`, found keyword `in` + //~| ERROR unexpected parentheses surrounding `for` loop head + const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types + } +} diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr new file mode 100644 index 000000000..3bad29f20 --- /dev/null +++ b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr @@ -0,0 +1,27 @@ +error: expected one of `)`, `,`, `@`, or `|`, found keyword `in` + --> $DIR/recover-for-loop-parens-around-head.rs:10:16 + | +LL | for ( elem in vec ) { + | ^^ expected one of `)`, `,`, `@`, or `|` + +error: unexpected parentheses surrounding `for` loop head + --> $DIR/recover-for-loop-parens-around-head.rs:10: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:38 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected `()`, found integer + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/recover-from-bad-variant.rs b/src/test/ui/parser/recover-from-bad-variant.rs new file mode 100644 index 000000000..e8887147c --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr new file mode 100644 index 000000000..483312c16 --- /dev/null +++ b/src/test/ui/parser/recover-from-bad-variant.stderr @@ -0,0 +1,40 @@ +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[E0532]: expected tuple struct or tuple variant, found struct variant `Enum::Foo` + --> $DIR/recover-from-bad-variant.rs:10:9 + | +LL | Foo { a: usize, b: usize }, + | -------------------------- `Enum::Foo` defined here +... +LL | Enum::Foo(a, b) => {} + | ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }` + +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: E0532, E0769. +For more information about an error, try `rustc --explain E0532`. diff --git a/src/test/ui/parser/recover-from-homoglyph.rs b/src/test/ui/parser/recover-from-homoglyph.rs new file mode 100644 index 000000000..99ce0d1a6 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-from-homoglyph.stderr b/src/test/ui/parser/recover-from-homoglyph.stderr new file mode 100644 index 000000000..f11ca9fd5 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-labeled-non-block-expr.fixed b/src/test/ui/parser/recover-labeled-non-block-expr.fixed new file mode 100644 index 000000000..fe546a719 --- /dev/null +++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed @@ -0,0 +1,27 @@ +// run-rustfix +#![feature(label_break_value)] +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/src/test/ui/parser/recover-labeled-non-block-expr.rs b/src/test/ui/parser/recover-labeled-non-block-expr.rs new file mode 100644 index 000000000..35862e2ee --- /dev/null +++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs @@ -0,0 +1,27 @@ +// run-rustfix +#![feature(label_break_value)] +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/src/test/ui/parser/recover-labeled-non-block-expr.stderr b/src/test/ui/parser/recover-labeled-non-block-expr.stderr new file mode 100644 index 000000000..04fc1203e --- /dev/null +++ b/src/test/ui/parser/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:4: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:6: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:7: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:9: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:12: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:26: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/src/test/ui/parser/recover-missing-semi.rs b/src/test/ui/parser/recover-missing-semi.rs new file mode 100644 index 000000000..f47d5e680 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-missing-semi.stderr b/src/test/ui/parser/recover-missing-semi.stderr new file mode 100644 index 000000000..ba4798285 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-quantified-closure.rs b/src/test/ui/parser/recover-quantified-closure.rs new file mode 100644 index 000000000..10af39b70 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-quantified-closure.stderr b/src/test/ui/parser/recover-quantified-closure.stderr new file mode 100644 index 000000000..39eec80f6 --- /dev/null +++ b/src/test/ui/parser/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:25 + | +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/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs new file mode 100644 index 000000000..2e5a99154 --- /dev/null +++ b/src/test/ui/parser/recover-range-pats.rs @@ -0,0 +1,160 @@ +// 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)] +#![feature(half_open_range_patterns)] +#![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/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr new file mode 100644 index 000000000..d0979b23f --- /dev/null +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -0,0 +1,484 @@ +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:22: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:24: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:35: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:37: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:60: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:64: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:75: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:81: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:82: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:83: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:85: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:85: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:91: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:92: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:93: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:95: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:95: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:105: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:115: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:121:12 + | +LL | if let ...3 = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:123:12 + | +LL | if let ...Y = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:125:12 + | +LL | if let ...true = 0 {} + | ^^^ help: use `..=` instead + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:128: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:128:12 + | +LL | if let ....3 = 0 {} + | ^^^ help: use `..=` instead + +error: range-to patterns with `...` are not allowed + --> $DIR/recover-range-pats.rs:150: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: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[E0586]: inclusive range with no end + --> $DIR/recover-range-pats.rs:155: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:42:13 + | +LL | if let 0...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + | +note: the lint level is defined here + --> $DIR/recover-range-pats.rs:8:9 + | +LL | #![deny(ellipsis_inclusive_range_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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:45: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:48: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:51: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:54: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:57: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:60: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:64: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:138: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:20: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:21: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:22: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:24:16 + | +LL | if let X.. .0 = 0 {} + | - ^^ - this expression has type `u8` + | | | + | | expected integer, 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:33: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:34: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:35: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:37:16 + | +LL | if let X..=.0 = 0 {} + | - ^^ - this expression has type `u8` + | | | + | | expected integer, 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:54: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:57: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:60: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:64:17 + | +LL | if let X... .0 = 0 {} + | - ^^ - this expression has type `u8` + | | | + | | expected integer, 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:73: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:75: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:83: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:85: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:93: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:95: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:103: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:105: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:113: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:115: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:125: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:128: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/src/test/ui/parser/recover-ref-dyn-mut.rs b/src/test/ui/parser/recover-ref-dyn-mut.rs new file mode 100644 index 000000000..3016275cc --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-ref-dyn-mut.stderr b/src/test/ui/parser/recover-ref-dyn-mut.stderr new file mode 100644 index 000000000..c048c8ea1 --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-struct.rs b/src/test/ui/parser/recover-struct.rs new file mode 100644 index 000000000..bfa5b454c --- /dev/null +++ b/src/test/ui/parser/recover-struct.rs @@ -0,0 +1,7 @@ +fn main() { + struct Test { + Very + Bad //~ ERROR found `Bad` + Stuff + } +} diff --git a/src/test/ui/parser/recover-struct.stderr b/src/test/ui/parser/recover-struct.stderr new file mode 100644 index 000000000..1b72184b0 --- /dev/null +++ b/src/test/ui/parser/recover-struct.stderr @@ -0,0 +1,10 @@ +error: expected `:`, found `Bad` + --> $DIR/recover-struct.rs:4:9 + | +LL | Very + | - expected `:` +LL | Bad + | ^^^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/ui/parser/recover-tuple-pat.rs b/src/test/ui/parser/recover-tuple-pat.rs new file mode 100644 index 000000000..7fded752d --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-tuple-pat.stderr b/src/test/ui/parser/recover-tuple-pat.stderr new file mode 100644 index 000000000..93a6a66a6 --- /dev/null +++ b/src/test/ui/parser/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 previous error + diff --git a/src/test/ui/parser/recover-tuple.rs b/src/test/ui/parser/recover-tuple.rs new file mode 100644 index 000000000..59e2695de --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recover-tuple.stderr b/src/test/ui/parser/recover-tuple.stderr new file mode 100644 index 000000000..88891b54b --- /dev/null +++ b/src/test/ui/parser/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/src/test/ui/parser/recovered-struct-variant.rs b/src/test/ui/parser/recovered-struct-variant.rs new file mode 100644 index 000000000..5b195dcc3 --- /dev/null +++ b/src/test/ui/parser/recovered-struct-variant.rs @@ -0,0 +1,13 @@ +enum Foo { + A { a, b: usize } + //~^ ERROR expected `:`, found `,` +} + +fn main() { + // no complaints about non-existing fields + let f = Foo::A { a:3, b: 4}; + match f { + // no complaints about non-existing fields + Foo::A {a, b} => {} + } +} diff --git a/src/test/ui/parser/recovered-struct-variant.stderr b/src/test/ui/parser/recovered-struct-variant.stderr new file mode 100644 index 000000000..51aaf8bb3 --- /dev/null +++ b/src/test/ui/parser/recovered-struct-variant.stderr @@ -0,0 +1,8 @@ +error: expected `:`, found `,` + --> $DIR/recovered-struct-variant.rs:2:10 + | +LL | A { a, b: usize } + | ^ expected `:` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/regions-out-of-scope-slice.rs b/src/test/ui/parser/regions-out-of-scope-slice.rs new file mode 100644 index 000000000..d223619e1 --- /dev/null +++ b/src/test/ui/parser/regions-out-of-scope-slice.rs @@ -0,0 +1,11 @@ +// This basically tests the parser's recovery on `'blk` in the wrong place. + +fn foo(cond: bool) { + let mut x; + + if cond { + x = &'blk [1,2,3]; //~ ERROR borrow expressions cannot be annotated with lifetimes + } +} + +fn main() {} diff --git a/src/test/ui/parser/regions-out-of-scope-slice.stderr b/src/test/ui/parser/regions-out-of-scope-slice.stderr new file mode 100644 index 000000000..bbc657ffd --- /dev/null +++ b/src/test/ui/parser/regions-out-of-scope-slice.stderr @@ -0,0 +1,11 @@ +error: borrow expressions cannot be annotated with lifetimes + --> $DIR/regions-out-of-scope-slice.rs:7:13 + | +LL | x = &'blk [1,2,3]; + | ^----^^^^^^^^ + | | + | annotated with lifetime here + | help: remove the lifetime annotation + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-closure-lifetime.rs b/src/test/ui/parser/removed-syntax-closure-lifetime.rs new file mode 100644 index 000000000..e807a1794 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-closure-lifetime.rs @@ -0,0 +1,2 @@ +type closure = Box<lt/fn()>; +//~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, `=`, or `>`, found `/` diff --git a/src/test/ui/parser/removed-syntax-closure-lifetime.stderr b/src/test/ui/parser/removed-syntax-closure-lifetime.stderr new file mode 100644 index 000000000..e107c6b78 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-closure-lifetime.stderr @@ -0,0 +1,13 @@ +error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, `=`, or `>`, found `/` + --> $DIR/removed-syntax-closure-lifetime.rs:1:22 + | +LL | type closure = Box<lt/fn()>; + | ^ expected one of 9 possible tokens + | +help: you might have meant to end the type parameters here + | +LL | type closure = Box<lt>/fn()>; + | + + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-enum-newtype.rs b/src/test/ui/parser/removed-syntax-enum-newtype.rs new file mode 100644 index 000000000..518f90b2b --- /dev/null +++ b/src/test/ui/parser/removed-syntax-enum-newtype.rs @@ -0,0 +1 @@ +enum e = isize; //~ ERROR expected one of `<`, `where`, or `{`, found `=` diff --git a/src/test/ui/parser/removed-syntax-enum-newtype.stderr b/src/test/ui/parser/removed-syntax-enum-newtype.stderr new file mode 100644 index 000000000..2daa6249b --- /dev/null +++ b/src/test/ui/parser/removed-syntax-enum-newtype.stderr @@ -0,0 +1,8 @@ +error: expected one of `<`, `where`, or `{`, found `=` + --> $DIR/removed-syntax-enum-newtype.rs:1:8 + | +LL | enum e = isize; + | ^ expected one of `<`, `where`, or `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-field-let.rs b/src/test/ui/parser/removed-syntax-field-let.rs new file mode 100644 index 000000000..6d64de296 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-field-let.rs @@ -0,0 +1,6 @@ +struct S { + let foo: (), + //~^ ERROR expected identifier, found keyword `let` +} + +fn main() {} diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr new file mode 100644 index 000000000..10be2e045 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-field-let.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found keyword `let` + --> $DIR/removed-syntax-field-let.rs:2:5 + | +LL | let foo: (), + | ^^^ expected identifier, found keyword + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.rs b/src/test/ui/parser/removed-syntax-field-semicolon.rs new file mode 100644 index 000000000..ac28e21ae --- /dev/null +++ b/src/test/ui/parser/removed-syntax-field-semicolon.rs @@ -0,0 +1,6 @@ +struct S { + bar: (); + //~^ ERROR expected `,`, or `}`, found `;` +} + +fn main() {} diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.stderr b/src/test/ui/parser/removed-syntax-field-semicolon.stderr new file mode 100644 index 000000000..fbefeb26a --- /dev/null +++ b/src/test/ui/parser/removed-syntax-field-semicolon.stderr @@ -0,0 +1,8 @@ +error: expected `,`, or `}`, found `;` + --> $DIR/removed-syntax-field-semicolon.rs:2:12 + | +LL | bar: (); + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-fixed-vec.rs b/src/test/ui/parser/removed-syntax-fixed-vec.rs new file mode 100644 index 000000000..560efecb9 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-fixed-vec.rs @@ -0,0 +1 @@ +type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*` diff --git a/src/test/ui/parser/removed-syntax-fixed-vec.stderr b/src/test/ui/parser/removed-syntax-fixed-vec.stderr new file mode 100644 index 000000000..a2b97544f --- /dev/null +++ b/src/test/ui/parser/removed-syntax-fixed-vec.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*` + --> $DIR/removed-syntax-fixed-vec.rs:1:17 + | +LL | type v = [isize * 3]; + | ^ expected one of 7 possible tokens + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-fn-sigil.rs b/src/test/ui/parser/removed-syntax-fn-sigil.rs new file mode 100644 index 000000000..725843429 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-fn-sigil.rs @@ -0,0 +1,3 @@ +fn main() { + let x: fn~() = || (); //~ ERROR expected `(`, found `~` +} diff --git a/src/test/ui/parser/removed-syntax-fn-sigil.stderr b/src/test/ui/parser/removed-syntax-fn-sigil.stderr new file mode 100644 index 000000000..196a5af47 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-fn-sigil.stderr @@ -0,0 +1,10 @@ +error: expected `(`, found `~` + --> $DIR/removed-syntax-fn-sigil.rs:2:14 + | +LL | let x: fn~() = || (); + | - ^ expected `(` + | | + | while parsing the type for `x` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-mode.rs b/src/test/ui/parser/removed-syntax-mode.rs new file mode 100644 index 000000000..a438db3b0 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-mode.rs @@ -0,0 +1,4 @@ +fn f(+x: isize) {} +//~^ ERROR expected parameter name, found `+` + +fn main() {} diff --git a/src/test/ui/parser/removed-syntax-mode.stderr b/src/test/ui/parser/removed-syntax-mode.stderr new file mode 100644 index 000000000..d0393b379 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-mode.stderr @@ -0,0 +1,8 @@ +error: expected parameter name, found `+` + --> $DIR/removed-syntax-mode.rs:1:6 + | +LL | fn f(+x: isize) {} + | ^ expected parameter name + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-mut-vec-expr.rs b/src/test/ui/parser/removed-syntax-mut-vec-expr.rs new file mode 100644 index 000000000..2ee95db5a --- /dev/null +++ b/src/test/ui/parser/removed-syntax-mut-vec-expr.rs @@ -0,0 +1,3 @@ +fn main() { + let v = [mut 1, 2, 3, 4]; //~ ERROR expected expression, found keyword `mut` +} diff --git a/src/test/ui/parser/removed-syntax-mut-vec-expr.stderr b/src/test/ui/parser/removed-syntax-mut-vec-expr.stderr new file mode 100644 index 000000000..313420fb9 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-mut-vec-expr.stderr @@ -0,0 +1,8 @@ +error: expected expression, found keyword `mut` + --> $DIR/removed-syntax-mut-vec-expr.rs:2:14 + | +LL | let v = [mut 1, 2, 3, 4]; + | ^^^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-mut-vec-ty.rs b/src/test/ui/parser/removed-syntax-mut-vec-ty.rs new file mode 100644 index 000000000..923a7ea37 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-mut-vec-ty.rs @@ -0,0 +1 @@ +type v = [mut isize]; //~ ERROR expected type, found keyword `mut` diff --git a/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr new file mode 100644 index 000000000..02b518e25 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr @@ -0,0 +1,8 @@ +error: expected type, found keyword `mut` + --> $DIR/removed-syntax-mut-vec-ty.rs:1:11 + | +LL | type v = [mut isize]; + | ^^^ expected type + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-ptr-lifetime.rs b/src/test/ui/parser/removed-syntax-ptr-lifetime.rs new file mode 100644 index 000000000..cc69af44a --- /dev/null +++ b/src/test/ui/parser/removed-syntax-ptr-lifetime.rs @@ -0,0 +1 @@ +type bptr = &lifetime/isize; //~ ERROR expected one of `!`, `(`, `::`, `;`, `<`, or `where`, found `/` diff --git a/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr b/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr new file mode 100644 index 000000000..914de43e6 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr @@ -0,0 +1,8 @@ +error: expected one of `!`, `(`, `::`, `;`, `<`, or `where`, found `/` + --> $DIR/removed-syntax-ptr-lifetime.rs:1:22 + | +LL | type bptr = &lifetime/isize; + | ^ expected one of `!`, `(`, `::`, `;`, `<`, or `where` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-record.rs b/src/test/ui/parser/removed-syntax-record.rs new file mode 100644 index 000000000..d1d91c8f7 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-record.rs @@ -0,0 +1 @@ +type t = { f: () }; //~ ERROR expected type, found `{` diff --git a/src/test/ui/parser/removed-syntax-record.stderr b/src/test/ui/parser/removed-syntax-record.stderr new file mode 100644 index 000000000..0a1655840 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-record.stderr @@ -0,0 +1,8 @@ +error: expected type, found `{` + --> $DIR/removed-syntax-record.rs:1:10 + | +LL | type t = { f: () }; + | ^ expected type + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-static-fn.rs b/src/test/ui/parser/removed-syntax-static-fn.rs new file mode 100644 index 000000000..cd643b874 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-static-fn.rs @@ -0,0 +1,10 @@ +struct S; + +impl S { + static fn f() {} + //~^ ERROR expected identifier, found keyword `fn` + //~| ERROR expected one of `:`, `;`, or `=` + //~| ERROR missing type for `static` item +} + +fn main() {} diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr new file mode 100644 index 000000000..04e34dc16 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-static-fn.stderr @@ -0,0 +1,25 @@ +error: expected identifier, found keyword `fn` + --> $DIR/removed-syntax-static-fn.rs:4:12 + | +LL | static fn f() {} + | ^^ expected identifier, found keyword + +error: expected one of `:`, `;`, or `=`, found `f` + --> $DIR/removed-syntax-static-fn.rs:4:15 + | +LL | impl S { + | - while parsing this item list starting here +LL | static fn f() {} + | ^ expected one of `:`, `;`, or `=` +... +LL | } + | - the item list ends here + +error: missing type for `static` item + --> $DIR/removed-syntax-static-fn.rs:4:12 + | +LL | static fn f() {} + | ^^ help: provide a type for the item: `r#fn: <type>` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-expr.rs b/src/test/ui/parser/removed-syntax-uniq-mut-expr.rs new file mode 100644 index 000000000..08ef4b432 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-uniq-mut-expr.rs @@ -0,0 +1,3 @@ +fn main() { + let a_box = box mut 42; //~ ERROR expected expression, found keyword `mut` +} diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr b/src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr new file mode 100644 index 000000000..63d2fdb8c --- /dev/null +++ b/src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr @@ -0,0 +1,8 @@ +error: expected expression, found keyword `mut` + --> $DIR/removed-syntax-uniq-mut-expr.rs:2:21 + | +LL | let a_box = box mut 42; + | ^^^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs b/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs new file mode 100644 index 000000000..a8dee5bbd --- /dev/null +++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs @@ -0,0 +1,2 @@ +type mut_box = Box<mut isize>; +//~^ ERROR expected one of `>`, a const expression, lifetime, or type, found keyword `mut` diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr new file mode 100644 index 000000000..39db0be9f --- /dev/null +++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr @@ -0,0 +1,8 @@ +error: expected one of `>`, a const expression, lifetime, or type, found keyword `mut` + --> $DIR/removed-syntax-uniq-mut-ty.rs:1:20 + | +LL | type mut_box = Box<mut isize>; + | ^^^ expected one of `>`, a const expression, lifetime, or type + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-with-1.rs b/src/test/ui/parser/removed-syntax-with-1.rs new file mode 100644 index 000000000..2c1e152dc --- /dev/null +++ b/src/test/ui/parser/removed-syntax-with-1.rs @@ -0,0 +1,10 @@ +fn main() { + struct S { + foo: (), + bar: (), + } + + let a = S { foo: (), bar: () }; + let b = S { foo: () with a, bar: () }; + //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with` +} diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr new file mode 100644 index 000000000..c3f747b61 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-with-1.stderr @@ -0,0 +1,11 @@ +error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with` + --> $DIR/removed-syntax-with-1.rs:8:25 + | +LL | let b = S { foo: () with a, bar: () }; + | - -^^^^ expected one of `,`, `.`, `?`, `}`, or an operator + | | | + | | help: try adding a comma: `,` + | while parsing this struct + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-with-2.rs b/src/test/ui/parser/removed-syntax-with-2.rs new file mode 100644 index 000000000..451057c66 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-with-2.rs @@ -0,0 +1,11 @@ +fn main() { + struct S { + foo: (), + bar: (), + } + + let a = S { foo: (), bar: () }; + let b = S { foo: (), with a }; + //~^ ERROR expected one of `,`, `:`, or `}`, found `a` + //~| ERROR missing field `bar` in initializer of `S` +} diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr new file mode 100644 index 000000000..c6ae1ce67 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-with-2.stderr @@ -0,0 +1,17 @@ +error: expected one of `,`, `:`, or `}`, found `a` + --> $DIR/removed-syntax-with-2.rs:8:31 + | +LL | let b = S { foo: (), with a }; + | - ^ expected one of `,`, `:`, or `}` + | | + | while parsing this struct + +error[E0063]: missing field `bar` in initializer of `S` + --> $DIR/removed-syntax-with-2.rs:8:13 + | +LL | let b = S { foo: (), with a }; + | ^ missing `bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0063`. diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs new file mode 100644 index 000000000..f29fd7a54 --- /dev/null +++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs @@ -0,0 +1,36 @@ +fn main() { + false == false == false; + //~^ ERROR comparison operators cannot be chained + //~| HELP split the comparison into two + + false == 0 < 2; + //~^ ERROR comparison operators cannot be chained + //~| HELP parenthesize the comparison + + f<X>(); + //~^ ERROR comparison operators cannot be chained + //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + + f<Result<Option<X>, Option<Option<X>>>(1, 2); + //~^ ERROR comparison operators cannot be chained + //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + + let _ = f<u8, i8>(); + //~^ ERROR expected one of + //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + + let _ = f<'_, i8>(); + //~^ ERROR expected one of + //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + //~| ERROR expected + + f<'_>(); + //~^ comparison operators cannot be chained + //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + //~| ERROR expected + + let _ = f<u8>; + //~^ ERROR comparison operators cannot be chained + //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + //~| HELP or use `(...)` if you meant to specify fn arguments +} diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr new file mode 100644 index 000000000..0bf52854e --- /dev/null +++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr @@ -0,0 +1,100 @@ +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:2:11 + | +LL | false == false == false; + | ^^ ^^ + | +help: split the comparison into two + | +LL | false == false && false == false; + | ++++++++ + +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:6:11 + | +LL | false == 0 < 2; + | ^^ ^ + | +help: parenthesize the comparison + | +LL | false == (0 < 2); + | + + + +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:10:6 + | +LL | f<X>(); + | ^ ^ + | +help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + | +LL | f::<X>(); + | ++ + +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:14:6 + | +LL | f<Result<Option<X>, Option<Option<X>>>(1, 2); + | ^ ^ + | +help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + | +LL | f::<Result<Option<X>, Option<Option<X>>>(1, 2); + | ++ + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` + --> $DIR/require-parens-for-chained-comparison.rs:18:17 + | +LL | let _ = f<u8, i8>(); + | ^ expected one of 8 possible tokens + | +help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + | +LL | let _ = f::<u8, i8>(); + | ++ + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/require-parens-for-chained-comparison.rs:22:17 + | +LL | let _ = f<'_, i8>(); + | ^ expected `while`, `for`, `loop` or `{` after a label + +error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, or an operator, found `,` + --> $DIR/require-parens-for-chained-comparison.rs:22:17 + | +LL | let _ = f<'_, i8>(); + | ^ expected one of 9 possible tokens + | +help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + | +LL | let _ = f::<'_, i8>(); + | ++ + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/require-parens-for-chained-comparison.rs:27:9 + | +LL | f<'_>(); + | ^ expected `while`, `for`, `loop` or `{` after a label + +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:27:6 + | +LL | f<'_>(); + | ^ ^ + | +help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + | +LL | f::<'_>(); + | ++ + +error: comparison operators cannot be chained + --> $DIR/require-parens-for-chained-comparison.rs:32:14 + | +LL | let _ = f<u8>; + | ^ ^ + | + = help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + = help: or use `(...)` if you meant to specify fn arguments + +error: aborting due to 10 previous errors + diff --git a/src/test/ui/parser/self-in-function-arg.rs b/src/test/ui/parser/self-in-function-arg.rs new file mode 100644 index 000000000..6172ffe1b --- /dev/null +++ b/src/test/ui/parser/self-in-function-arg.rs @@ -0,0 +1,3 @@ +fn foo(x:i32, self: i32) -> i32 { self } //~ ERROR unexpected `self` parameter in function + +fn main() {} diff --git a/src/test/ui/parser/self-in-function-arg.stderr b/src/test/ui/parser/self-in-function-arg.stderr new file mode 100644 index 000000000..47d8381b0 --- /dev/null +++ b/src/test/ui/parser/self-in-function-arg.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` parameter in function + --> $DIR/self-in-function-arg.rs:1:15 + | +LL | fn foo(x:i32, self: i32) -> i32 { self } + | ^^^^ must be the first parameter of an associated function + +error: aborting due to previous error + diff --git a/src/test/ui/parser/self-param-semantic-fail.rs b/src/test/ui/parser/self-param-semantic-fail.rs new file mode 100644 index 000000000..621aab279 --- /dev/null +++ b/src/test/ui/parser/self-param-semantic-fail.rs @@ -0,0 +1,64 @@ +// This test ensures that `self` is semantically rejected +// in contexts with `FnDecl` but outside of associated `fn`s. +// FIXME(Centril): For now closures are an exception. + +fn main() {} + +fn free() { + fn f1(self) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f2(mut self) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f3(&self) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f4(&mut self) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f5<'a>(&'a self) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f6<'a>(&'a mut self) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f7(self: u8) {} + //~^ ERROR `self` parameter is only allowed in associated functions + fn f8(mut self: u8) {} + //~^ ERROR `self` parameter is only allowed in associated functions +} + +extern "C" { + fn f1(self); + //~^ ERROR `self` parameter is only allowed in associated functions + fn f2(mut self); + //~^ ERROR `self` parameter is only allowed in associated functions + //~| ERROR patterns aren't allowed in + fn f3(&self); + //~^ ERROR `self` parameter is only allowed in associated functions + fn f4(&mut self); + //~^ ERROR `self` parameter is only allowed in associated functions + fn f5<'a>(&'a self); + //~^ ERROR `self` parameter is only allowed in associated functions + fn f6<'a>(&'a mut self); + //~^ ERROR `self` parameter is only allowed in associated functions + fn f7(self: u8); + //~^ ERROR `self` parameter is only allowed in associated functions + fn f8(mut self: u8); +//~^ ERROR `self` parameter is only allowed in associated functions +//~| ERROR patterns aren't allowed in +} + +type X1 = fn(self); +//~^ ERROR `self` parameter is only allowed in associated functions +type X2 = fn(mut self); +//~^ ERROR `self` parameter is only allowed in associated functions +//~| ERROR patterns aren't allowed in +type X3 = fn(&self); +//~^ ERROR `self` parameter is only allowed in associated functions +type X4 = fn(&mut self); +//~^ ERROR `self` parameter is only allowed in associated functions +type X5 = for<'a> fn(&'a self); +//~^ ERROR `self` parameter is only allowed in associated functions +type X6 = for<'a> fn(&'a mut self); +//~^ ERROR `self` parameter is only allowed in associated functions +type X7 = fn(self: u8); +//~^ ERROR `self` parameter is only allowed in associated functions +type X8 = fn(mut self: u8); +//~^ ERROR `self` parameter is only allowed in associated functions +//~| ERROR patterns aren't allowed in diff --git a/src/test/ui/parser/self-param-semantic-fail.stderr b/src/test/ui/parser/self-param-semantic-fail.stderr new file mode 100644 index 000000000..e5d679773 --- /dev/null +++ b/src/test/ui/parser/self-param-semantic-fail.stderr @@ -0,0 +1,220 @@ +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:8:11 + | +LL | fn f1(self) {} + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:10:11 + | +LL | fn f2(mut self) {} + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:12:11 + | +LL | fn f3(&self) {} + | ^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:14:11 + | +LL | fn f4(&mut self) {} + | ^^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:16:15 + | +LL | fn f5<'a>(&'a self) {} + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:18:15 + | +LL | fn f6<'a>(&'a mut self) {} + | ^^^^^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:20:11 + | +LL | fn f7(self: u8) {} + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:22:11 + | +LL | fn f8(mut self: u8) {} + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:27:11 + | +LL | fn f1(self); + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:29:11 + | +LL | fn f2(mut self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0130]: patterns aren't allowed in foreign function declarations + --> $DIR/self-param-semantic-fail.rs:29:11 + | +LL | fn f2(mut self); + | ^^^^^^^^ pattern not allowed in foreign function + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:32:11 + | +LL | fn f3(&self); + | ^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:34:11 + | +LL | fn f4(&mut self); + | ^^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:36:15 + | +LL | fn f5<'a>(&'a self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:38:15 + | +LL | fn f6<'a>(&'a mut self); + | ^^^^^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:40:11 + | +LL | fn f7(self: u8); + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:42:11 + | +LL | fn f8(mut self: u8); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0130]: patterns aren't allowed in foreign function declarations + --> $DIR/self-param-semantic-fail.rs:42:11 + | +LL | fn f8(mut self: u8); + | ^^^^^^^^ pattern not allowed in foreign function + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:47:14 + | +LL | type X1 = fn(self); + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:49:14 + | +LL | type X2 = fn(mut self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/self-param-semantic-fail.rs:49:14 + | +LL | type X2 = fn(mut self); + | ^^^^^^^^ + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:52:14 + | +LL | type X3 = fn(&self); + | ^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:54:14 + | +LL | type X4 = fn(&mut self); + | ^^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:56:22 + | +LL | type X5 = for<'a> fn(&'a self); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:58:22 + | +LL | type X6 = for<'a> fn(&'a mut self); + | ^^^^^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:60:14 + | +LL | type X7 = fn(self: u8); + | ^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: `self` parameter is only allowed in associated functions + --> $DIR/self-param-semantic-fail.rs:62:14 + | +LL | type X8 = fn(mut self: u8); + | ^^^^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0561]: patterns aren't allowed in function pointer types + --> $DIR/self-param-semantic-fail.rs:62:14 + | +LL | type X8 = fn(mut self: u8); + | ^^^^^^^^ + +error: aborting due to 28 previous errors + +Some errors have detailed explanations: E0130, E0561. +For more information about an error, try `rustc --explain E0130`. diff --git a/src/test/ui/parser/self-param-syntactic-pass.rs b/src/test/ui/parser/self-param-syntactic-pass.rs new file mode 100644 index 000000000..d7bb7863c --- /dev/null +++ b/src/test/ui/parser/self-param-syntactic-pass.rs @@ -0,0 +1,66 @@ +// This test ensures that `self` is syntactically accepted in all places an `FnDecl` is parsed. +// FIXME(Centril): For now closures are an exception. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn free() { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +extern "C" { + fn f(self); + fn f(mut self); + fn f(&self); + fn f(&mut self); + fn f(&'a self); + fn f(&'a mut self); + fn f(self: u8); + fn f(mut self: u8); +} + +#[cfg(FALSE)] +trait X { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +impl X for Y { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +impl X for Y { + type X = fn(self); + type X = fn(mut self); + type X = fn(&self); + type X = fn(&mut self); + type X = fn(&'a self); + type X = fn(&'a mut self); + type X = fn(self: u8); + type X = fn(mut self: u8); +} diff --git a/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs b/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs new file mode 100644 index 000000000..ee14c55d2 --- /dev/null +++ b/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs @@ -0,0 +1,10 @@ +// Issue #62863 +// ignore-tidy-cr + +// Note: if you see ^M in this file, that's how your editor renders literal `\r` + +/// This do
c comment contains
three isolated `\r`
symbols +//~^ ERROR bare CR not allowed in doc-comment +//~| ERROR bare CR not allowed in doc-comment +//~| ERROR bare CR not allowed in doc-comment +fn main() {} diff --git a/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr b/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr new file mode 100644 index 000000000..07066fc22 --- /dev/null +++ b/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr @@ -0,0 +1,20 @@ +error: bare CR not allowed in doc-comment + --> $DIR/several-carriage-returns-in-doc-comment.rs:6:12 + | +LL | /// This do
c comment contains
three isolated `\r`
symbols + | ^ + +error: bare CR not allowed in doc-comment + --> $DIR/several-carriage-returns-in-doc-comment.rs:6:32 + | +LL | /// This do
c comment contains
three isolated `\r`
symbols + | ^ + +error: bare CR not allowed in doc-comment + --> $DIR/several-carriage-returns-in-doc-comment.rs:6:52 + | +LL | /// This do
c comment contains
three isolated `\r`
symbols + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs new file mode 100644 index 000000000..a25051808 --- /dev/null +++ b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs @@ -0,0 +1,2 @@ + +#!B //~ expected `[`, found `B` diff --git a/src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr new file mode 100644 index 000000000..896a9dc83 --- /dev/null +++ b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr @@ -0,0 +1,8 @@ +error: expected `[`, found `B` + --> $DIR/issue-71471-ignore-tidy.rs:2:3 + | +LL | #!B + | ^ expected `[` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/shebang/multiline-attrib.rs b/src/test/ui/parser/shebang/multiline-attrib.rs new file mode 100644 index 000000000..931c94c7f --- /dev/null +++ b/src/test/ui/parser/shebang/multiline-attrib.rs @@ -0,0 +1,7 @@ +#! +[allow(unused_variables)] +// check-pass + +fn main() { + let x = 5; +} diff --git a/src/test/ui/parser/shebang/regular-attrib.rs b/src/test/ui/parser/shebang/regular-attrib.rs new file mode 100644 index 000000000..ca8fb0830 --- /dev/null +++ b/src/test/ui/parser/shebang/regular-attrib.rs @@ -0,0 +1,5 @@ +#![allow(unused_variables)] +// check-pass +fn main() { + let x = 5; +} diff --git a/src/test/ui/parser/shebang/shebang-and-attrib.rs b/src/test/ui/parser/shebang/shebang-and-attrib.rs new file mode 100644 index 000000000..61b89c655 --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-and-attrib.rs @@ -0,0 +1,9 @@ +#!/usr/bin/env run-cargo-script + +// check-pass +#![allow(unused_variables)] + + +fn main() { + let x = 5; +} diff --git a/src/test/ui/parser/shebang/shebang-comment.rs b/src/test/ui/parser/shebang/shebang-comment.rs new file mode 100644 index 000000000..2b1ab0c57 --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-comment.rs @@ -0,0 +1,6 @@ +#!//bin/bash + +// check-pass +fn main() { + println!("a valid shebang (that is also a rust comment)") +} diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.rs b/src/test/ui/parser/shebang/shebang-doc-comment.rs new file mode 100644 index 000000000..72866753e --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-doc-comment.rs @@ -0,0 +1,3 @@ +#!///bin/bash +[allow(unused_variables)] +//~^ ERROR expected item, found `[` diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.stderr b/src/test/ui/parser/shebang/shebang-doc-comment.stderr new file mode 100644 index 000000000..2227d45ec --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-doc-comment.stderr @@ -0,0 +1,8 @@ +error: expected item, found `[` + --> $DIR/shebang-doc-comment.rs:2:1 + | +LL | [allow(unused_variables)] + | ^ expected item + +error: aborting due to previous error + diff --git a/src/test/ui/parser/shebang/shebang-empty.rs b/src/test/ui/parser/shebang/shebang-empty.rs new file mode 100644 index 000000000..e38cc637e --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-empty.rs @@ -0,0 +1,4 @@ +#! + +// check-pass +fn main() {} diff --git a/src/test/ui/parser/shebang/shebang-must-start-file.rs b/src/test/ui/parser/shebang/shebang-must-start-file.rs new file mode 100644 index 000000000..e0392572d --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-must-start-file.rs @@ -0,0 +1,6 @@ +// something on the first line for tidy +#!/bin/bash //~ expected `[`, found `/` + +fn main() { + println!("ok!"); +} diff --git a/src/test/ui/parser/shebang/shebang-must-start-file.stderr b/src/test/ui/parser/shebang/shebang-must-start-file.stderr new file mode 100644 index 000000000..50543e8bd --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-must-start-file.stderr @@ -0,0 +1,8 @@ +error: expected `[`, found `/` + --> $DIR/shebang-must-start-file.rs:2:3 + | +LL | #!/bin/bash + | ^ expected `[` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/shebang/shebang-space.rs b/src/test/ui/parser/shebang/shebang-space.rs new file mode 100644 index 000000000..0978b759d --- /dev/null +++ b/src/test/ui/parser/shebang/shebang-space.rs @@ -0,0 +1,5 @@ +#! + +// check-pass +// ignore-tidy-end-whitespace +fn main() {} diff --git a/src/test/ui/parser/shebang/sneaky-attrib.rs b/src/test/ui/parser/shebang/sneaky-attrib.rs new file mode 100644 index 000000000..b406cc3aa --- /dev/null +++ b/src/test/ui/parser/shebang/sneaky-attrib.rs @@ -0,0 +1,16 @@ +#!//bin/bash + + +// This could not possibly be a shebang & also a valid rust file, since a Rust file +// can't start with `[` +/* + [ (mixing comments to also test that we ignore both types of comments) + + */ + +[allow(unused_variables)] + +// check-pass +fn main() { + let x = 5; +} diff --git a/src/test/ui/parser/shebang/valid-shebang.rs b/src/test/ui/parser/shebang/valid-shebang.rs new file mode 100644 index 000000000..e480d3da3 --- /dev/null +++ b/src/test/ui/parser/shebang/valid-shebang.rs @@ -0,0 +1,6 @@ +#!/usr/bin/env run-cargo-script + +// check-pass +fn main() { + println!("Hello World!"); +} diff --git a/src/test/ui/parser/similar-tokens.rs b/src/test/ui/parser/similar-tokens.rs new file mode 100644 index 000000000..e3024c61a --- /dev/null +++ b/src/test/ui/parser/similar-tokens.rs @@ -0,0 +1,11 @@ +#![allow(unused_imports)] + +pub mod x { + pub struct A; + pub struct B; +} + +// `.` is similar to `,` so list parsing should continue to closing `}` +use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.` + +fn main() {} diff --git a/src/test/ui/parser/similar-tokens.stderr b/src/test/ui/parser/similar-tokens.stderr new file mode 100644 index 000000000..90acfc052 --- /dev/null +++ b/src/test/ui/parser/similar-tokens.stderr @@ -0,0 +1,11 @@ +error: expected one of `,`, `::`, `as`, or `}`, found `.` + --> $DIR/similar-tokens.rs:9:10 + | +LL | use x::{A. B}; + | ^ + | | + | expected one of `,`, `::`, `as`, or `}` + | help: missing `,` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/stmt_expr_attrs_placement.rs b/src/test/ui/parser/stmt_expr_attrs_placement.rs new file mode 100644 index 000000000..5e9d29a15 --- /dev/null +++ b/src/test/ui/parser/stmt_expr_attrs_placement.rs @@ -0,0 +1,38 @@ +#![feature(stmt_expr_attributes)] + +// Test that various placements of the inner attribute are parsed correctly, +// or not. + +fn main() { + let a = #![allow(warnings)] (1, 2); + //~^ ERROR an inner attribute is not permitted in this context + + let b = (#![allow(warnings)] 1, 2); + //~^ ERROR an inner attribute is not permitted in this context + + let c = { + #![allow(warnings)] + (#![allow(warnings)] 1, 2) + //~^ ERROR an inner attribute is not permitted in this context + }; + + let d = { + #![allow(warnings)] + let e = (#![allow(warnings)] 1, 2); + //~^ ERROR an inner attribute is not permitted in this context + e + }; + + let e = [#![allow(warnings)] 1, 2]; + //~^ ERROR an inner attribute is not permitted in this context + + let f = [#![allow(warnings)] 1; 0]; + //~^ ERROR an inner attribute is not permitted in this context + + let g = match true { #![allow(warnings)] _ => {} }; + + + struct MyStruct { field: u8 } + let h = MyStruct { #![allow(warnings)] field: 0 }; + //~^ ERROR an inner attribute is not permitted in this context +} diff --git a/src/test/ui/parser/stmt_expr_attrs_placement.stderr b/src/test/ui/parser/stmt_expr_attrs_placement.stderr new file mode 100644 index 000000000..bf4005698 --- /dev/null +++ b/src/test/ui/parser/stmt_expr_attrs_placement.stderr @@ -0,0 +1,65 @@ +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:7:13 + | +LL | let a = #![allow(warnings)] (1, 2); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:10:14 + | +LL | let b = (#![allow(warnings)] 1, 2); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:15:10 + | +LL | (#![allow(warnings)] 1, 2) + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:21:18 + | +LL | let e = (#![allow(warnings)] 1, 2); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:26:14 + | +LL | let e = [#![allow(warnings)] 1, 2]; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:29:14 + | +LL | let f = [#![allow(warnings)] 1; 0]; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/stmt_expr_attrs_placement.rs:36:24 + | +LL | let h = MyStruct { #![allow(warnings)] field: 0 }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/stripped-nested-outline-mod-pass.rs b/src/test/ui/parser/stripped-nested-outline-mod-pass.rs new file mode 100644 index 000000000..1b4669a43 --- /dev/null +++ b/src/test/ui/parser/stripped-nested-outline-mod-pass.rs @@ -0,0 +1,13 @@ +// Expansion drives parsing, so conditional compilation will strip +// out outline modules and we will never attempt parsing them. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +mod foo { + mod bar { + mod baz; // This was an error before. + } +} diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed b/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed new file mode 100644 index 000000000..28191b826 --- /dev/null +++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(dead_code)] + +enum E { + A, +} + +struct S { + field1: i32, //~ ERROR default values on `struct` fields aren't supported + field2: E, //~ ERROR default values on `struct` fields aren't supported + field3: i32, //~ ERROR default values on `struct` fields aren't supported + field4: i32, //~ ERROR default values on `struct` fields aren't supported + field5: E, //~ ERROR default values on `struct` fields aren't supported + field6: E, //~ ERROR default values on `struct` fields aren't supported +} + +struct S1 { + field1: i32, //~ ERROR expected `,`, or `}`, found `field2` + field2: E, //~ ERROR expected `,`, or `}`, found `field3` + field3: i32, //~ ERROR default values on `struct` fields aren't supported + field4: i32, //~ ERROR default values on `struct` fields aren't supported + field5: E, //~ ERROR default values on `struct` fields aren't supported + field6: E, //~ ERROR default values on `struct` fields aren't supported +} + +struct S2 { + field1 : i32, //~ ERROR expected `:`, found `=` + field2: E, //~ ERROR expected `:`, found `;` +} + +const fn foo(_: i32) -> E { + E::A +} + +fn main() {} diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs b/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs new file mode 100644 index 000000000..924cb08a9 --- /dev/null +++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(dead_code)] + +enum E { + A, +} + +struct S { + field1: i32 = 42, //~ ERROR default values on `struct` fields aren't supported + field2: E = E::A, //~ ERROR default values on `struct` fields aren't supported + field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported + field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported + field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported + field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported +} + +struct S1 { + field1: i32 //~ ERROR expected `,`, or `}`, found `field2` + field2: E //~ ERROR expected `,`, or `}`, found `field3` + field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported + field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported + field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported + field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported +} + +struct S2 { + field1 = i32, //~ ERROR expected `:`, found `=` + field2; E, //~ ERROR expected `:`, found `;` +} + +const fn foo(_: i32) -> E { + E::A +} + +fn main() {} diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr b/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr new file mode 100644 index 000000000..7f16ebcfc --- /dev/null +++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr @@ -0,0 +1,92 @@ +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:9:16 + | +LL | field1: i32 = 42, + | ^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:10:14 + | +LL | field2: E = E::A, + | ^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:11:16 + | +LL | field3: i32 = 1 + 2, + | ^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:12:16 + | +LL | field4: i32 = { 1 + 2 }, + | ^^^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:13:14 + | +LL | field5: E = foo(42), + | ^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:14:14 + | +LL | field6: E = { foo(42) }, + | ^^^^^^^^^^^^^^ help: remove this unsupported default value + +error: expected `,`, or `}`, found `field2` + --> $DIR/struct-default-values-and-missing-field-separator.rs:18:16 + | +LL | field1: i32 + | ^ help: try adding a comma: `,` + +error: expected `,`, or `}`, found `field3` + --> $DIR/struct-default-values-and-missing-field-separator.rs:19:14 + | +LL | field2: E + | ^ help: try adding a comma: `,` + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:20:16 + | +LL | field3: i32 = 1 + 2, + | ^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:21:16 + | +LL | field4: i32 = { 1 + 2 }, + | ^^^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:22:14 + | +LL | field5: E = foo(42), + | ^^^^^^^^^^ help: remove this unsupported default value + +error: default values on `struct` fields aren't supported + --> $DIR/struct-default-values-and-missing-field-separator.rs:23:14 + | +LL | field6: E = { foo(42) }, + | ^^^^^^^^^^^^^^ help: remove this unsupported default value + +error: expected `:`, found `=` + --> $DIR/struct-default-values-and-missing-field-separator.rs:27:12 + | +LL | field1 = i32, + | ^ + | | + | expected `:` + | help: field names and their types are separated with `:` + +error: expected `:`, found `;` + --> $DIR/struct-default-values-and-missing-field-separator.rs:28:11 + | +LL | field2; E, + | ^ + | | + | expected `:` + | help: field names and their types are separated with `:` + +error: aborting due to 14 previous errors + diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.rs b/src/test/ui/parser/struct-field-numeric-shorthand.rs new file mode 100644 index 000000000..645abd9c7 --- /dev/null +++ b/src/test/ui/parser/struct-field-numeric-shorthand.rs @@ -0,0 +1,9 @@ +struct Rgb(u8, u8, u8); + +fn main() { + let _ = Rgb { 0, 1, 2 }; + //~^ ERROR expected identifier, found `0` + //~| ERROR expected identifier, found `1` + //~| ERROR expected identifier, found `2` + //~| ERROR missing fields `0`, `1` and `2` in initializer of `Rgb` +} diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.stderr b/src/test/ui/parser/struct-field-numeric-shorthand.stderr new file mode 100644 index 000000000..bfb8a931b --- /dev/null +++ b/src/test/ui/parser/struct-field-numeric-shorthand.stderr @@ -0,0 +1,33 @@ +error: expected identifier, found `0` + --> $DIR/struct-field-numeric-shorthand.rs:4:19 + | +LL | let _ = Rgb { 0, 1, 2 }; + | --- ^ expected identifier + | | + | while parsing this struct + +error: expected identifier, found `1` + --> $DIR/struct-field-numeric-shorthand.rs:4:22 + | +LL | let _ = Rgb { 0, 1, 2 }; + | --- ^ expected identifier + | | + | while parsing this struct + +error: expected identifier, found `2` + --> $DIR/struct-field-numeric-shorthand.rs:4:25 + | +LL | let _ = Rgb { 0, 1, 2 }; + | --- ^ expected identifier + | | + | while parsing this struct + +error[E0063]: missing fields `0`, `1` and `2` in initializer of `Rgb` + --> $DIR/struct-field-numeric-shorthand.rs:4:13 + | +LL | let _ = Rgb { 0, 1, 2 }; + | ^^^ missing `0`, `1` and `2` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0063`. diff --git a/src/test/ui/parser/struct-literal-in-for.rs b/src/test/ui/parser/struct-literal-in-for.rs new file mode 100644 index 000000000..3227ae37b --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-for.rs @@ -0,0 +1,17 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + for x in Foo { //~ ERROR struct literals are not allowed here + x: 3 //~^ ERROR `bool` is not an iterator + }.hi() { + println!("yo"); + } +} diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr new file mode 100644 index 000000000..4b191710c --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-for.stderr @@ -0,0 +1,31 @@ +error: struct literals are not allowed here + --> $DIR/struct-literal-in-for.rs:12:14 + | +LL | for x in Foo { + | ______________^ +LL | | x: 3 +LL | | }.hi() { + | |_____^ + | +help: surround the struct literal with parentheses + | +LL ~ for x in (Foo { +LL | x: 3 +LL ~ }).hi() { + | + +error[E0277]: `bool` is not an iterator + --> $DIR/struct-literal-in-for.rs:12:14 + | +LL | for x in Foo { + | ______________^ +LL | | x: 3 +LL | | }.hi() { + | |__________^ `bool` is not an iterator + | + = help: the trait `Iterator` is not implemented for `bool` + = note: required because of the requirements on the impl of `IntoIterator` for `bool` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/parser/struct-literal-in-if.rs b/src/test/ui/parser/struct-literal-in-if.rs new file mode 100644 index 000000000..2ce2c8f18 --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-if.rs @@ -0,0 +1,17 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + if Foo { //~ ERROR struct literals are not allowed here + x: 3 + }.hi() { + println!("yo"); + } +} diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr new file mode 100644 index 000000000..b5a9864bb --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-if.stderr @@ -0,0 +1,18 @@ +error: struct literals are not allowed here + --> $DIR/struct-literal-in-if.rs:12:8 + | +LL | if Foo { + | ________^ +LL | | x: 3 +LL | | }.hi() { + | |_____^ + | +help: surround the struct literal with parentheses + | +LL ~ if (Foo { +LL | x: 3 +LL ~ }).hi() { + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/struct-literal-in-match-discriminant.rs b/src/test/ui/parser/struct-literal-in-match-discriminant.rs new file mode 100644 index 000000000..ce132df5a --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-match-discriminant.rs @@ -0,0 +1,13 @@ +struct Foo { + x: isize, +} + +fn main() { + match Foo { //~ ERROR struct literals are not allowed here + x: 3 + } { + Foo { + x: x + } => {} + } +} diff --git a/src/test/ui/parser/struct-literal-in-match-discriminant.stderr b/src/test/ui/parser/struct-literal-in-match-discriminant.stderr new file mode 100644 index 000000000..692b4d735 --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-match-discriminant.stderr @@ -0,0 +1,18 @@ +error: struct literals are not allowed here + --> $DIR/struct-literal-in-match-discriminant.rs:6:11 + | +LL | match Foo { + | ___________^ +LL | | x: 3 +LL | | } { + | |_____^ + | +help: surround the struct literal with parentheses + | +LL ~ match (Foo { +LL | x: 3 +LL ~ }) { + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/struct-literal-in-match-guard.rs b/src/test/ui/parser/struct-literal-in-match-guard.rs new file mode 100644 index 000000000..bf0551b5c --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-match-guard.rs @@ -0,0 +1,18 @@ +// check-pass + +// Unlike `if` condition, `match` guards accept struct literals. +// This is detected in <https://github.com/rust-lang/rust/pull/74566#issuecomment-663613705>. + +#[derive(PartialEq)] +struct Foo { + x: isize, +} + +fn foo(f: Foo) { + match () { + () if f == Foo { x: 42 } => {} + _ => {} + } +} + +fn main() {} diff --git a/src/test/ui/parser/struct-literal-in-while.rs b/src/test/ui/parser/struct-literal-in-while.rs new file mode 100644 index 000000000..5000ce85b --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-while.rs @@ -0,0 +1,17 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + while Foo { //~ ERROR struct literals are not allowed here + x: 3 + }.hi() { + println!("yo"); + } +} diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr new file mode 100644 index 000000000..17e9277e0 --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-while.stderr @@ -0,0 +1,18 @@ +error: struct literals are not allowed here + --> $DIR/struct-literal-in-while.rs:12:11 + | +LL | while Foo { + | ___________^ +LL | | x: 3 +LL | | }.hi() { + | |_____^ + | +help: surround the struct literal with parentheses + | +LL ~ while (Foo { +LL | x: 3 +LL ~ }).hi() { + | + +error: aborting due to previous error + diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.rs b/src/test/ui/parser/struct-literal-restrictions-in-lamda.rs new file mode 100644 index 000000000..e185153dc --- /dev/null +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.rs @@ -0,0 +1,17 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + while || Foo { //~ ERROR struct literals are not allowed here + x: 3 //~^ ERROR mismatched types + }.hi() { + println!("yo"); + } +} diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr new file mode 100644 index 000000000..0852c7cb4 --- /dev/null +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr @@ -0,0 +1,37 @@ +error: struct literals are not allowed here + --> $DIR/struct-literal-restrictions-in-lamda.rs:12:14 + | +LL | while || Foo { + | ______________^ +LL | | x: 3 +LL | | }.hi() { + | |_____^ + | +help: surround the struct literal with parentheses + | +LL ~ while || (Foo { +LL | x: 3 +LL ~ }).hi() { + | + +error[E0308]: mismatched types + --> $DIR/struct-literal-restrictions-in-lamda.rs:12:11 + | +LL | while || Foo { + | ___________^ +LL | | x: 3 +LL | | }.hi() { + | |__________^ expected `bool`, found closure + | + = note: expected type `bool` + found closure `[closure@$DIR/struct-literal-restrictions-in-lamda.rs:12:11: 12:13]` +help: use parentheses to call this closure + | +LL ~ while (|| Foo { +LL | x: 3 +LL ~ }.hi())() { + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/struct-literal-variant-in-if.rs b/src/test/ui/parser/struct-literal-variant-in-if.rs new file mode 100644 index 000000000..4ef8effaf --- /dev/null +++ b/src/test/ui/parser/struct-literal-variant-in-if.rs @@ -0,0 +1,25 @@ +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +enum E { + V { field: bool }, + I { field1: bool, field2: usize }, + J { field: isize }, + K { field: &'static str}, +} +fn test_E(x: E) { + let field = true; + if x == E::V { field } {} + //~^ ERROR expected value, found struct variant `E::V` + //~| ERROR mismatched types + if x == E::I { field1: true, field2: 42 } {} + //~^ ERROR struct literals are not allowed here + if x == E::V { field: false } {} + //~^ ERROR struct literals are not allowed here + if x == E::J { field: -42 } {} + //~^ ERROR struct literals are not allowed here + if x == E::K { field: "" } {} + //~^ ERROR struct literals are not allowed here + let y: usize = (); + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr new file mode 100644 index 000000000..4cffbe433 --- /dev/null +++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr @@ -0,0 +1,76 @@ +error: struct literals are not allowed here + --> $DIR/struct-literal-variant-in-if.rs:13:13 + | +LL | if x == E::I { field1: true, field2: 42 } {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: surround the struct literal with parentheses + | +LL | if x == (E::I { field1: true, field2: 42 }) {} + | + + + +error: struct literals are not allowed here + --> $DIR/struct-literal-variant-in-if.rs:15:13 + | +LL | if x == E::V { field: false } {} + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: surround the struct literal with parentheses + | +LL | if x == (E::V { field: false }) {} + | + + + +error: struct literals are not allowed here + --> $DIR/struct-literal-variant-in-if.rs:17:13 + | +LL | if x == E::J { field: -42 } {} + | ^^^^^^^^^^^^^^^^^^^ + | +help: surround the struct literal with parentheses + | +LL | if x == (E::J { field: -42 }) {} + | + + + +error: struct literals are not allowed here + --> $DIR/struct-literal-variant-in-if.rs:19:13 + | +LL | if x == E::K { field: "" } {} + | ^^^^^^^^^^^^^^^^^^ + | +help: surround the struct literal with parentheses + | +LL | if x == (E::K { field: "" }) {} + | + + + +error[E0423]: expected value, found struct variant `E::V` + --> $DIR/struct-literal-variant-in-if.rs:10:13 + | +LL | if x == E::V { field } {} + | ^^^^ not a value + | +help: surround the struct literal with parentheses + | +LL | if x == (E::V { field }) {} + | + + + +error[E0308]: mismatched types + --> $DIR/struct-literal-variant-in-if.rs:10:20 + | +LL | if x == E::V { field } {} + | ---------------^^^^^-- + | | | + | | expected `()`, found `bool` + | expected this to be `()` + +error[E0308]: mismatched types + --> $DIR/struct-literal-variant-in-if.rs:21:20 + | +LL | let y: usize = (); + | ----- ^^ expected `usize`, found `()` + | | + | expected due to this + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0308, E0423. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/suggest-semi-in-array.rs b/src/test/ui/parser/suggest-semi-in-array.rs new file mode 100644 index 000000000..9ce2e59e5 --- /dev/null +++ b/src/test/ui/parser/suggest-semi-in-array.rs @@ -0,0 +1,5 @@ +fn main() { + let v = [1 + 2]; + //~^ ERROR expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `2` +} diff --git a/src/test/ui/parser/suggest-semi-in-array.stderr b/src/test/ui/parser/suggest-semi-in-array.stderr new file mode 100644 index 000000000..d7cd6efae --- /dev/null +++ b/src/test/ui/parser/suggest-semi-in-array.stderr @@ -0,0 +1,10 @@ +error: expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `2` + --> $DIR/suggest-semi-in-array.rs:3:5 + | +LL | let v = [1 + | - expected one of `,`, `.`, `;`, `?`, `]`, or an operator +LL | 2]; + | ^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.rs b/src/test/ui/parser/tag-variant-disr-non-nullary.rs new file mode 100644 index 000000000..a9cfdd549 --- /dev/null +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.rs @@ -0,0 +1,12 @@ +enum Color { + Red = 0xff0000, + //~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants + Green = 0x00ff00, + Blue = 0x0000ff, + Black = 0x000000, + White = 0xffffff, + Other(usize), + Other2(usize, usize), +} + +fn main() {} diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr new file mode 100644 index 000000000..79f044a06 --- /dev/null +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr @@ -0,0 +1,25 @@ +error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants + --> $DIR/tag-variant-disr-non-nullary.rs:2:11 + | +LL | Red = 0xff0000, + | ^^^^^^^^ disallowed custom discriminant +LL | +LL | Green = 0x00ff00, + | ^^^^^^^^ disallowed custom discriminant +LL | Blue = 0x0000ff, + | ^^^^^^^^ disallowed custom discriminant +LL | Black = 0x000000, + | ^^^^^^^^ disallowed custom discriminant +LL | White = 0xffffff, + | ^^^^^^^^ disallowed custom discriminant +LL | Other(usize), + | ------------ tuple variant defined here +LL | Other2(usize, usize), + | -------------------- tuple variant defined here + | + = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.rs b/src/test/ui/parser/trailing-carriage-return-in-string.rs new file mode 100644 index 000000000..5d3c31944 --- /dev/null +++ b/src/test/ui/parser/trailing-carriage-return-in-string.rs @@ -0,0 +1,14 @@ +// Issue #11669 + +// ignore-tidy-cr + +fn main() { + // \r\n + let ok = "This is \ + a test"; + // \r only + let bad = "This is \
a test"; + //~^ ERROR unknown character escape: `\r` + //~| HELP this is an isolated carriage return + +} diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr new file mode 100644 index 000000000..8a44e0270 --- /dev/null +++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr @@ -0,0 +1,10 @@ +error: unknown character escape: `\r` + --> $DIR/trailing-carriage-return-in-string.rs:10:25 + | +LL | let bad = "This is \
a test"; + | ^ unknown character escape + | + = help: this is an isolated carriage return; consider checking your editor and version control settings + +error: aborting due to previous error + diff --git a/src/test/ui/parser/trailing-plus-in-bounds.rs b/src/test/ui/parser/trailing-plus-in-bounds.rs new file mode 100644 index 000000000..400649bcf --- /dev/null +++ b/src/test/ui/parser/trailing-plus-in-bounds.rs @@ -0,0 +1,9 @@ +// check-pass + +#![allow(bare_trait_objects)] + +use std::fmt::Debug; + +fn main() { + let x: Box<Debug+> = Box::new(3) as Box<Debug+>; // Trailing `+` is OK +} diff --git a/src/test/ui/parser/trailing-question-in-macro-type.rs b/src/test/ui/parser/trailing-question-in-macro-type.rs new file mode 100644 index 000000000..e2a681ddd --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-macro-type.rs @@ -0,0 +1,14 @@ +macro_rules! fn_expr { + ($return_type:ty : $body:expr) => { + (|| -> $return_type { $body })() + }; + ($body:expr) => { + (|| $body)() + }; +} + + +fn main() { + fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + //~^ ERROR cannot find value `o` in this scope +} diff --git a/src/test/ui/parser/trailing-question-in-macro-type.stderr b/src/test/ui/parser/trailing-question-in-macro-type.stderr new file mode 100644 index 000000000..c096ae04f --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-macro-type.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `o` in this scope + --> $DIR/trailing-question-in-macro-type.rs:12:15 + | +LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/trailing-question-in-type.fixed b/src/test/ui/parser/trailing-question-in-type.fixed new file mode 100644 index 000000000..6ea24484e --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-type.fixed @@ -0,0 +1,10 @@ +// run-rustfix + +fn foo() -> Option<i32> { //~ ERROR invalid `?` in type + let x: Option<i32> = Some(1); //~ ERROR invalid `?` in type + x +} + +fn main() { + let _: Option<i32> = foo(); +} diff --git a/src/test/ui/parser/trailing-question-in-type.rs b/src/test/ui/parser/trailing-question-in-type.rs new file mode 100644 index 000000000..b1c508365 --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-type.rs @@ -0,0 +1,10 @@ +// run-rustfix + +fn foo() -> i32? { //~ ERROR invalid `?` in type + let x: i32? = Some(1); //~ ERROR invalid `?` in type + x +} + +fn main() { + let _: Option<i32> = foo(); +} diff --git a/src/test/ui/parser/trailing-question-in-type.stderr b/src/test/ui/parser/trailing-question-in-type.stderr new file mode 100644 index 000000000..a3cd419c0 --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-type.stderr @@ -0,0 +1,24 @@ +error: invalid `?` in type + --> $DIR/trailing-question-in-type.rs:3:16 + | +LL | fn foo() -> i32? { + | ^ `?` is only allowed on expressions, not types + | +help: if you meant to express that the type might not contain a value, use the `Option` wrapper type + | +LL | fn foo() -> Option<i32> { + | +++++++ ~ + +error: invalid `?` in type + --> $DIR/trailing-question-in-type.rs:4:15 + | +LL | let x: i32? = Some(1); + | ^ `?` is only allowed on expressions, not types + | +help: if you meant to express that the type might not contain a value, use the `Option` wrapper type + | +LL | let x: Option<i32> = Some(1); + | +++++++ ~ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/trait-bounds-not-on-impl.rs b/src/test/ui/parser/trait-bounds-not-on-impl.rs new file mode 100644 index 000000000..02563847e --- /dev/null +++ b/src/test/ui/parser/trait-bounds-not-on-impl.rs @@ -0,0 +1,7 @@ +trait Foo {} + +struct Bar; + +impl Foo + Owned for Bar {} //~ ERROR expected a trait, found type + +fn main() { } diff --git a/src/test/ui/parser/trait-bounds-not-on-impl.stderr b/src/test/ui/parser/trait-bounds-not-on-impl.stderr new file mode 100644 index 000000000..8d2d5e3d7 --- /dev/null +++ b/src/test/ui/parser/trait-bounds-not-on-impl.stderr @@ -0,0 +1,8 @@ +error: expected a trait, found type + --> $DIR/trait-bounds-not-on-impl.rs:5:6 + | +LL | impl Foo + Owned for Bar {} + | ^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs new file mode 100644 index 000000000..f2d97b7ba --- /dev/null +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs @@ -0,0 +1,12 @@ +#![feature(specialization)] //~ WARN the feature `specialization` is incomplete + +fn main() {} + +trait X { + default const A: u8; //~ ERROR `default` is only allowed on items in trait impls + default const B: u8 = 0; //~ ERROR `default` is only allowed on items in trait impls + default type D; //~ ERROR `default` is only allowed on items in trait impls + default type C: Ord; //~ ERROR `default` is only allowed on items in trait impls + default fn f1(); //~ ERROR `default` is only allowed on items in trait impls + default fn f2() {} //~ ERROR `default` is only allowed on items in trait impls +} diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr new file mode 100644 index 000000000..76fa86033 --- /dev/null +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr @@ -0,0 +1,60 @@ +error: `default` is only allowed on items in trait impls + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5 + | +LL | default const A: u8; + | -------^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5 + | +LL | default const B: u8 = 0; + | -------^^^^^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5 + | +LL | default type D; + | -------^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5 + | +LL | default type C: Ord; + | -------^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5 + | +LL | default fn f1(); + | -------^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5 + | +LL | default fn f2() {} + | -------^^^^^^^^ + | | + | `default` because of this + +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/trait-item-with-defaultness-fail-semantic.rs:1:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + +error: aborting due to 6 previous errors; 1 warning emitted + diff --git a/src/test/ui/parser/trait-item-with-defaultness-pass.rs b/src/test/ui/parser/trait-item-with-defaultness-pass.rs new file mode 100644 index 000000000..a6318bd99 --- /dev/null +++ b/src/test/ui/parser/trait-item-with-defaultness-pass.rs @@ -0,0 +1,13 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +trait X { + default const A: u8; + default const B: u8 = 0; + default type D; + default type C: Ord; + default fn f1(); + default fn f2() {} +} diff --git a/src/test/ui/parser/trait-object-bad-parens.rs b/src/test/ui/parser/trait-object-bad-parens.rs new file mode 100644 index 000000000..8e267c744 --- /dev/null +++ b/src/test/ui/parser/trait-object-bad-parens.rs @@ -0,0 +1,16 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] +#![allow(bare_trait_objects)] + +auto trait Auto {} + +fn main() { + let _: Box<((Auto)) + Auto>; + //~^ ERROR expected a path on the left-hand side of `+`, not `((Auto))` + let _: Box<(Auto + Auto) + Auto>; + //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto + Auto)` + let _: Box<(Auto +) + Auto>; + //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto)` + let _: Box<(dyn Auto) + Auto>; + //~^ ERROR expected a path on the left-hand side of `+`, not `(dyn Auto)` +} diff --git a/src/test/ui/parser/trait-object-bad-parens.stderr b/src/test/ui/parser/trait-object-bad-parens.stderr new file mode 100644 index 000000000..74e484eeb --- /dev/null +++ b/src/test/ui/parser/trait-object-bad-parens.stderr @@ -0,0 +1,27 @@ +error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))` + --> $DIR/trait-object-bad-parens.rs:8:16 + | +LL | let _: Box<((Auto)) + Auto>; + | ^^^^^^^^^^^^^^^ expected a path + +error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)` + --> $DIR/trait-object-bad-parens.rs:10:16 + | +LL | let _: Box<(Auto + Auto) + Auto>; + | ^^^^^^^^^^^^^^^^^^^^ expected a path + +error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)` + --> $DIR/trait-object-bad-parens.rs:12:16 + | +LL | let _: Box<(Auto +) + Auto>; + | ^^^^^^^^^^^^^^^ expected a path + +error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)` + --> $DIR/trait-object-bad-parens.rs:14:16 + | +LL | let _: Box<(dyn Auto) + Auto>; + | ^^^^^^^^^^^^^^^^^ expected a path + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0178`. diff --git a/src/test/ui/parser/trait-object-delimiters.rs b/src/test/ui/parser/trait-object-delimiters.rs new file mode 100644 index 000000000..b5258eebb --- /dev/null +++ b/src/test/ui/parser/trait-object-delimiters.rs @@ -0,0 +1,17 @@ +// edition:2018 + +fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type +//~^ ERROR only auto traits can be used as additional traits in a trait object + +fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds + +fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{` +//~^ ERROR expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{` +//~| ERROR at least one trait is required for an object type + +fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<` + +fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} //~ ERROR invalid `dyn` keyword +//~^ ERROR only auto traits can be used as additional traits in a trait object + +fn main() {} diff --git a/src/test/ui/parser/trait-object-delimiters.stderr b/src/test/ui/parser/trait-object-delimiters.stderr new file mode 100644 index 000000000..6eb9c7238 --- /dev/null +++ b/src/test/ui/parser/trait-object-delimiters.stderr @@ -0,0 +1,78 @@ +error: ambiguous `+` in a type + --> $DIR/trait-object-delimiters.rs:3:13 + | +LL | fn foo1(_: &dyn Drop + AsRef<str>) {} + | ^^^^^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(dyn Drop + AsRef<str>)` + +error: incorrect braces around trait bounds + --> $DIR/trait-object-delimiters.rs:6:17 + | +LL | fn foo2(_: &dyn (Drop + AsRef<str>)) {} + | ^ ^ + | +help: remove the parentheses + | +LL - fn foo2(_: &dyn (Drop + AsRef<str>)) {} +LL + fn foo2(_: &dyn Drop + AsRef<str>) {} + | + +error: expected parameter name, found `{` + --> $DIR/trait-object-delimiters.rs:8:17 + | +LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {} + | ^ expected parameter name + +error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{` + --> $DIR/trait-object-delimiters.rs:8:17 + | +LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {} + | -^ expected one of 9 possible tokens + | | + | help: missing `,` + +error: expected identifier, found `<` + --> $DIR/trait-object-delimiters.rs:12:17 + | +LL | fn foo4(_: &dyn <Drop + AsRef<str>>) {} + | ^ expected identifier + +error: invalid `dyn` keyword + --> $DIR/trait-object-delimiters.rs:14:25 + | +LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} + | ^^^ help: remove this keyword + | + = help: `dyn` is only needed at the start of a trait `+`-separated list + +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/trait-object-delimiters.rs:3:24 + | +LL | fn foo1(_: &dyn Drop + AsRef<str>) {} + | ---- ^^^^^^^^^^ additional non-auto trait + | | + | first non-auto trait + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> + +error[E0224]: at least one trait is required for an object type + --> $DIR/trait-object-delimiters.rs:8:13 + | +LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {} + | ^^^ + +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/trait-object-delimiters.rs:14:29 + | +LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} + | ---- ^^^^^^^^^^ additional non-auto trait + | | + | first non-auto trait + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0224, E0225. +For more information about an error, try `rustc --explain E0224`. diff --git a/src/test/ui/parser/trait-object-lifetime-parens.rs b/src/test/ui/parser/trait-object-lifetime-parens.rs new file mode 100644 index 000000000..f44ebe5ba --- /dev/null +++ b/src/test/ui/parser/trait-object-lifetime-parens.rs @@ -0,0 +1,13 @@ +#![allow(bare_trait_objects)] + +trait Trait {} + +fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not supported + +fn check<'a>() { + let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported + // FIXME: It'd be great if we could add suggestion to the following case. + let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+` +} + +fn main() {} diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr new file mode 100644 index 000000000..9c7a9662c --- /dev/null +++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr @@ -0,0 +1,20 @@ +error: parenthesized lifetime bounds are not supported + --> $DIR/trait-object-lifetime-parens.rs:5:21 + | +LL | fn f<'a, T: Trait + ('a)>() {} + | ^^^^ help: remove the parentheses + +error: parenthesized lifetime bounds are not supported + --> $DIR/trait-object-lifetime-parens.rs:8:24 + | +LL | let _: Box<Trait + ('a)>; + | ^^^^ help: remove the parentheses + +error: lifetime in trait object type must be followed by `+` + --> $DIR/trait-object-lifetime-parens.rs:10:17 + | +LL | let _: Box<('a) + Trait>; + | ^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/trait-object-polytrait-priority.rs b/src/test/ui/parser/trait-object-polytrait-priority.rs new file mode 100644 index 000000000..63425f3e2 --- /dev/null +++ b/src/test/ui/parser/trait-object-polytrait-priority.rs @@ -0,0 +1,10 @@ +#![allow(bare_trait_objects)] + +trait Trait<'a> {} + +fn main() { + let _: &for<'a> Trait<'a> + 'static; + //~^ ERROR expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>` + //~| HELP try adding parentheses + //~| SUGGESTION &(for<'a> Trait<'a> + 'static) +} diff --git a/src/test/ui/parser/trait-object-polytrait-priority.stderr b/src/test/ui/parser/trait-object-polytrait-priority.stderr new file mode 100644 index 000000000..a6add6079 --- /dev/null +++ b/src/test/ui/parser/trait-object-polytrait-priority.stderr @@ -0,0 +1,9 @@ +error[E0178]: expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>` + --> $DIR/trait-object-polytrait-priority.rs:6:12 + | +LL | let _: &for<'a> Trait<'a> + 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try adding parentheses: `&(for<'a> Trait<'a> + 'static)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0178`. diff --git a/src/test/ui/parser/trait-object-trait-parens.rs b/src/test/ui/parser/trait-object-trait-parens.rs new file mode 100644 index 000000000..438034bc3 --- /dev/null +++ b/src/test/ui/parser/trait-object-trait-parens.rs @@ -0,0 +1,23 @@ +trait Trait<'a> {} + +trait Obj {} + +fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {} + +fn main() { + let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; + //~^ ERROR `?Trait` is not permitted in trait object types + //~| ERROR only auto traits can be used as additional traits + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; + //~^ ERROR `?Trait` is not permitted in trait object types + //~| ERROR only auto traits can be used as additional traits + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; + //~^ ERROR `?Trait` is not permitted in trait object types + //~| ERROR only auto traits can be used as additional traits + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition +} diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr new file mode 100644 index 000000000..7ee965bd2 --- /dev/null +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -0,0 +1,97 @@ +error: `?Trait` is not permitted in trait object types + --> $DIR/trait-object-trait-parens.rs:8:24 + | +LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; + | ^^^^^^^^ + +error: `?Trait` is not permitted in trait object types + --> $DIR/trait-object-trait-parens.rs:13:16 + | +LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; + | ^^^^^^ + +error: `?Trait` is not permitted in trait object types + --> $DIR/trait-object-trait-parens.rs:18:44 + | +LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; + | ^^^^^^^^ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/trait-object-trait-parens.rs:8:16 + | +LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = 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> +help: use `dyn` + | +LL - let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; +LL + let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>; + | + +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/trait-object-trait-parens.rs:8:35 + | +LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; + | ----- ^^^^^^^^^^^^^^^^^^^ additional non-auto trait + | | + | first non-auto trait + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + for<'a> Trait<'a> {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/trait-object-trait-parens.rs:13:16 + | +LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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> +help: use `dyn` + | +LL - let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; +LL + let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>; + | + +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/trait-object-trait-parens.rs:13:47 + | +LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; + | ------------------- ^^^^^ additional non-auto trait + | | + | first non-auto trait + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/trait-object-trait-parens.rs:18:16 + | +LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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> +help: use `dyn` + | +LL - let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; +LL + let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>; + | + +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/trait-object-trait-parens.rs:18:36 + | +LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; + | ----------------- ^^^^^ additional non-auto trait + | | + | first non-auto trait + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> + +error: aborting due to 6 previous errors; 3 warnings emitted + +For more information about this error, try `rustc --explain E0225`. diff --git a/src/test/ui/parser/trait-plusequal-splitting.rs b/src/test/ui/parser/trait-plusequal-splitting.rs new file mode 100644 index 000000000..6ca677450 --- /dev/null +++ b/src/test/ui/parser/trait-plusequal-splitting.rs @@ -0,0 +1,8 @@ +// Fixes issue where `+` in generics weren't parsed if they were part of a `+=`. + +// check-pass + +struct Whitespace<T: Clone + = ()> { t: T } +struct TokenSplit<T: Clone += ()> { t: T } + +fn main() {} diff --git a/src/test/ui/parser/trait-pub-assoc-const.rs b/src/test/ui/parser/trait-pub-assoc-const.rs new file mode 100644 index 000000000..219ffa309 --- /dev/null +++ b/src/test/ui/parser/trait-pub-assoc-const.rs @@ -0,0 +1,6 @@ +trait Foo { + pub const Foo: u32; + //~^ ERROR unnecessary visibility qualifier +} + +fn main() {} diff --git a/src/test/ui/parser/trait-pub-assoc-const.stderr b/src/test/ui/parser/trait-pub-assoc-const.stderr new file mode 100644 index 000000000..efd09a036 --- /dev/null +++ b/src/test/ui/parser/trait-pub-assoc-const.stderr @@ -0,0 +1,9 @@ +error[E0449]: unnecessary visibility qualifier + --> $DIR/trait-pub-assoc-const.rs:2:5 + | +LL | pub const Foo: u32; + | ^^^ `pub` not permitted here because it's implied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0449`. diff --git a/src/test/ui/parser/trait-pub-assoc-ty.rs b/src/test/ui/parser/trait-pub-assoc-ty.rs new file mode 100644 index 000000000..a78dfbdcd --- /dev/null +++ b/src/test/ui/parser/trait-pub-assoc-ty.rs @@ -0,0 +1,6 @@ +trait Foo { + pub type Foo; + //~^ ERROR unnecessary visibility qualifier +} + +fn main() {} diff --git a/src/test/ui/parser/trait-pub-assoc-ty.stderr b/src/test/ui/parser/trait-pub-assoc-ty.stderr new file mode 100644 index 000000000..e76373f5c --- /dev/null +++ b/src/test/ui/parser/trait-pub-assoc-ty.stderr @@ -0,0 +1,9 @@ +error[E0449]: unnecessary visibility qualifier + --> $DIR/trait-pub-assoc-ty.rs:2:5 + | +LL | pub type Foo; + | ^^^ `pub` not permitted here because it's implied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0449`. diff --git a/src/test/ui/parser/trait-pub-method.rs b/src/test/ui/parser/trait-pub-method.rs new file mode 100644 index 000000000..1f6ee028a --- /dev/null +++ b/src/test/ui/parser/trait-pub-method.rs @@ -0,0 +1,6 @@ +trait Foo { + pub fn foo(); + //~^ ERROR unnecessary visibility qualifier +} + +fn main() {} diff --git a/src/test/ui/parser/trait-pub-method.stderr b/src/test/ui/parser/trait-pub-method.stderr new file mode 100644 index 000000000..0e3fe027c --- /dev/null +++ b/src/test/ui/parser/trait-pub-method.stderr @@ -0,0 +1,9 @@ +error[E0449]: unnecessary visibility qualifier + --> $DIR/trait-pub-method.rs:2:5 + | +LL | pub fn foo(); + | ^^^ `pub` not permitted here because it's implied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0449`. diff --git a/src/test/ui/parser/type-alias-where-fixable.fixed b/src/test/ui/parser/type-alias-where-fixable.fixed new file mode 100644 index 000000000..41dd10676 --- /dev/null +++ b/src/test/ui/parser/type-alias-where-fixable.fixed @@ -0,0 +1,30 @@ +// check-pass +// run-rustfix + +#![feature(generic_associated_types)] + +trait Trait { + // Fine. + type Assoc where u32: Copy; + // Fine. + type Assoc2 where u32: Copy, i32: Copy; +} + +impl Trait for u32 { + // Not fine, suggests moving. + type Assoc = () where u32: Copy; + //~^ WARNING where clause not allowed here + // Not fine, suggests moving `u32: Copy` + type Assoc2 = () where i32: Copy, u32: Copy; + //~^ WARNING where clause not allowed here +} + +impl Trait for i32 { + // Fine. + type Assoc = () where u32: Copy; + // Not fine, suggests moving both. + type Assoc2 = () where u32: Copy, i32: Copy; + //~^ WARNING where clause not allowed here +} + +fn main() {} diff --git a/src/test/ui/parser/type-alias-where-fixable.rs b/src/test/ui/parser/type-alias-where-fixable.rs new file mode 100644 index 000000000..562a530a7 --- /dev/null +++ b/src/test/ui/parser/type-alias-where-fixable.rs @@ -0,0 +1,30 @@ +// check-pass +// run-rustfix + +#![feature(generic_associated_types)] + +trait Trait { + // Fine. + type Assoc where u32: Copy; + // Fine. + type Assoc2 where u32: Copy, i32: Copy; +} + +impl Trait for u32 { + // Not fine, suggests moving. + type Assoc where u32: Copy = (); + //~^ WARNING where clause not allowed here + // Not fine, suggests moving `u32: Copy` + type Assoc2 where u32: Copy = () where i32: Copy; + //~^ WARNING where clause not allowed here +} + +impl Trait for i32 { + // Fine. + type Assoc = () where u32: Copy; + // Not fine, suggests moving both. + type Assoc2 where u32: Copy, i32: Copy = (); + //~^ WARNING where clause not allowed here +} + +fn main() {} diff --git a/src/test/ui/parser/type-alias-where-fixable.stderr b/src/test/ui/parser/type-alias-where-fixable.stderr new file mode 100644 index 000000000..abfeb62fc --- /dev/null +++ b/src/test/ui/parser/type-alias-where-fixable.stderr @@ -0,0 +1,42 @@ +warning: where clause not allowed here + --> $DIR/type-alias-where-fixable.rs:15:16 + | +LL | type Assoc where u32: Copy = (); + | ^^^^^^^^^^^^^^^ + | + = note: `#[warn(deprecated_where_clause_location)]` on by default + = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information +help: move it to the end of the type declaration + | +LL - type Assoc where u32: Copy = (); +LL + type Assoc = () where u32: Copy; + | + +warning: where clause not allowed here + --> $DIR/type-alias-where-fixable.rs:18:17 + | +LL | type Assoc2 where u32: Copy = () where i32: Copy; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information +help: move it to the end of the type declaration + | +LL - type Assoc2 where u32: Copy = () where i32: Copy; +LL + type Assoc2 = () where i32: Copy, u32: Copy; + | + +warning: where clause not allowed here + --> $DIR/type-alias-where-fixable.rs:26:17 + | +LL | type Assoc2 where u32: Copy, i32: Copy = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information +help: move it to the end of the type declaration + | +LL - type Assoc2 where u32: Copy, i32: Copy = (); +LL + type Assoc2 = () where u32: Copy, i32: Copy; + | + +warning: 3 warnings emitted + diff --git a/src/test/ui/parser/type-alias-where.rs b/src/test/ui/parser/type-alias-where.rs new file mode 100644 index 000000000..f6e7dfb7b --- /dev/null +++ b/src/test/ui/parser/type-alias-where.rs @@ -0,0 +1,13 @@ +// check-fail + +#![feature(generic_associated_types)] + +// Fine, but lints as unused +type Foo where u32: Copy = (); +// Not fine. +type Bar = () where u32: Copy; +//~^ ERROR where clauses are not allowed +type Baz = () where; +//~^ ERROR where clauses are not allowed + +fn main() {} diff --git a/src/test/ui/parser/type-alias-where.stderr b/src/test/ui/parser/type-alias-where.stderr new file mode 100644 index 000000000..8789d2665 --- /dev/null +++ b/src/test/ui/parser/type-alias-where.stderr @@ -0,0 +1,18 @@ +error: where clauses are not allowed after the type for type aliases + --> $DIR/type-alias-where.rs:8:15 + | +LL | type Bar = () where u32: Copy; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information + +error: where clauses are not allowed after the type for type aliases + --> $DIR/type-alias-where.rs:10:15 + | +LL | type Baz = () where; + | ^^^^^ + | + = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.rs b/src/test/ui/parser/type-parameters-in-field-exprs.rs new file mode 100644 index 000000000..4cd77ebbd --- /dev/null +++ b/src/test/ui/parser/type-parameters-in-field-exprs.rs @@ -0,0 +1,17 @@ +struct Foo { + x: isize, + y: isize, +} + +fn main() { + let f = Foo { + x: 1, + y: 2, + }; + f.x::<isize>; + //~^ ERROR field expressions cannot have generic arguments + f.x::<>; + //~^ ERROR field expressions cannot have generic arguments + f.x::(); + //~^ ERROR field expressions cannot have generic arguments +} diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr new file mode 100644 index 000000000..ce7364d35 --- /dev/null +++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr @@ -0,0 +1,20 @@ +error: field expressions cannot have generic arguments + --> $DIR/type-parameters-in-field-exprs.rs:11:10 + | +LL | f.x::<isize>; + | ^^^^^^^ + +error: field expressions cannot have generic arguments + --> $DIR/type-parameters-in-field-exprs.rs:13:10 + | +LL | f.x::<>; + | ^^ + +error: field expressions cannot have generic arguments + --> $DIR/type-parameters-in-field-exprs.rs:15:7 + | +LL | f.x::(); + | ^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/unbalanced-doublequote.rs b/src/test/ui/parser/unbalanced-doublequote.rs new file mode 100644 index 000000000..f21316205 --- /dev/null +++ b/src/test/ui/parser/unbalanced-doublequote.rs @@ -0,0 +1,6 @@ +// error-pattern: unterminated double quote string + + +fn main() { + " +} diff --git a/src/test/ui/parser/unbalanced-doublequote.stderr b/src/test/ui/parser/unbalanced-doublequote.stderr new file mode 100644 index 000000000..94b300a7b --- /dev/null +++ b/src/test/ui/parser/unbalanced-doublequote.stderr @@ -0,0 +1,10 @@ +error[E0765]: unterminated double quote string + --> $DIR/unbalanced-doublequote.rs:5:5 + | +LL | / " +LL | | } + | |__^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0765`. diff --git a/src/test/ui/parser/unclosed-braces.rs b/src/test/ui/parser/unclosed-braces.rs new file mode 100644 index 000000000..ed94fff38 --- /dev/null +++ b/src/test/ui/parser/unclosed-braces.rs @@ -0,0 +1,22 @@ +struct S { + x: [usize; 3], +} + +fn foo() { + { + { + println!("hi"); + } + } +} + +fn main() { +//~^ NOTE unclosed delimiter + { + { + //~^ NOTE this delimiter might not be properly closed... + foo(); + } + //~^ NOTE ...as it matches this but it has different indentation +} +//~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/unclosed-braces.stderr b/src/test/ui/parser/unclosed-braces.stderr new file mode 100644 index 000000000..cbc5f8de4 --- /dev/null +++ b/src/test/ui/parser/unclosed-braces.stderr @@ -0,0 +1,17 @@ +error: this file contains an unclosed delimiter + --> $DIR/unclosed-braces.rs:22:52 + | +LL | fn main() { + | - unclosed delimiter +... +LL | { + | - this delimiter might not be properly closed... +... +LL | } + | - ...as it matches this but it has different indentation +... +LL | + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.rs b/src/test/ui/parser/unclosed-delimiter-in-dep.rs new file mode 100644 index 000000000..6db1b66e9 --- /dev/null +++ b/src/test/ui/parser/unclosed-delimiter-in-dep.rs @@ -0,0 +1,6 @@ +mod unclosed_delim_mod; + +fn main() { + let _: usize = unclosed_delim_mod::new(); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr new file mode 100644 index 000000000..1366ef1bb --- /dev/null +++ b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr @@ -0,0 +1,25 @@ +error: mismatched closing delimiter: `}` + --> $DIR/unclosed_delim_mod.rs:5:7 + | +LL | pub fn new() -> Result<Value, ()> { + | - closing delimiter possibly meant for this +LL | Ok(Value { + | ^ unclosed delimiter +LL | } +LL | } + | ^ mismatched closing delimiter + +error[E0308]: mismatched types + --> $DIR/unclosed-delimiter-in-dep.rs:4:20 + | +LL | let _: usize = unclosed_delim_mod::new(); + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found enum `Result` + | | + | expected due to this + | + = note: expected type `usize` + found enum `Result<Value, ()>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/unclosed_delim_mod.rs b/src/test/ui/parser/unclosed_delim_mod.rs new file mode 100644 index 000000000..d977d2c03 --- /dev/null +++ b/src/test/ui/parser/unclosed_delim_mod.rs @@ -0,0 +1,8 @@ +fn main() {} + +pub struct Value {} +pub fn new() -> Result<Value, ()> { + Ok(Value { + } +} +//~^ ERROR mismatched closing delimiter diff --git a/src/test/ui/parser/unclosed_delim_mod.stderr b/src/test/ui/parser/unclosed_delim_mod.stderr new file mode 100644 index 000000000..a46d020b9 --- /dev/null +++ b/src/test/ui/parser/unclosed_delim_mod.stderr @@ -0,0 +1,13 @@ +error: mismatched closing delimiter: `}` + --> $DIR/unclosed_delim_mod.rs:5:7 + | +LL | pub fn new() -> Result<Value, ()> { + | - closing delimiter possibly meant for this +LL | Ok(Value { + | ^ unclosed delimiter +LL | } +LL | } + | ^ mismatched closing delimiter + +error: aborting due to previous error + diff --git a/src/test/ui/parser/underscore-suffix-for-float.rs b/src/test/ui/parser/underscore-suffix-for-float.rs new file mode 100644 index 000000000..c9b7eced0 --- /dev/null +++ b/src/test/ui/parser/underscore-suffix-for-float.rs @@ -0,0 +1,4 @@ +fn main() { + let a = 42._; //~ ERROR expected identifier, found reserved identifier `_` + //~| ERROR `{integer}` is a primitive type and therefore doesn't have fields +} diff --git a/src/test/ui/parser/underscore-suffix-for-float.stderr b/src/test/ui/parser/underscore-suffix-for-float.stderr new file mode 100644 index 000000000..a5f3b6551 --- /dev/null +++ b/src/test/ui/parser/underscore-suffix-for-float.stderr @@ -0,0 +1,15 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore-suffix-for-float.rs:2:16 + | +LL | let a = 42._; + | ^ expected identifier, found reserved identifier + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/underscore-suffix-for-float.rs:2:16 + | +LL | let a = 42._; + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/parser/underscore-suffix-for-string.rs b/src/test/ui/parser/underscore-suffix-for-string.rs new file mode 100644 index 000000000..2e0ebe2cf --- /dev/null +++ b/src/test/ui/parser/underscore-suffix-for-string.rs @@ -0,0 +1,8 @@ +// check-pass + +fn main() { + let _ = "Foo"_; + //~^ WARNING underscore literal suffix is not allowed + //~| WARNING this was previously accepted + //~| NOTE issue #42326 +} diff --git a/src/test/ui/parser/underscore-suffix-for-string.stderr b/src/test/ui/parser/underscore-suffix-for-string.stderr new file mode 100644 index 000000000..00c7657f1 --- /dev/null +++ b/src/test/ui/parser/underscore-suffix-for-string.stderr @@ -0,0 +1,11 @@ +warning: underscore literal suffix is not allowed + --> $DIR/underscore-suffix-for-string.rs:4:18 + | +LL | let _ = "Foo"_; + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: see issue #42326 <https://github.com/rust-lang/rust/issues/42326> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/parser/underscore_item_not_const.rs b/src/test/ui/parser/underscore_item_not_const.rs new file mode 100644 index 000000000..c01ac4752 --- /dev/null +++ b/src/test/ui/parser/underscore_item_not_const.rs @@ -0,0 +1,16 @@ +// Test that various non-const items do not syntactically permit `_` as a name. + +static _: () = (); //~ ERROR expected identifier, found reserved identifier `_` +struct _(); //~ ERROR expected identifier, found reserved identifier `_` +enum _ {} //~ ERROR expected identifier, found reserved identifier `_` +fn _() {} //~ ERROR expected identifier, found reserved identifier `_` +mod _ {} //~ ERROR expected identifier, found reserved identifier `_` +type _ = (); //~ ERROR expected identifier, found reserved identifier `_` +use _; //~ ERROR expected identifier, found reserved identifier `_` +use _ as g; //~ ERROR expected identifier, found reserved identifier `_` +trait _ {} //~ ERROR expected identifier, found reserved identifier `_` +trait _ = Copy; //~ ERROR expected identifier, found reserved identifier `_` +macro_rules! _ { () => {} } //~ ERROR expected identifier, found reserved identifier `_` +union _ { f: u8 } //~ ERROR expected one of `!` or `::`, found reserved identifier `_` + +fn main() {} diff --git a/src/test/ui/parser/underscore_item_not_const.stderr b/src/test/ui/parser/underscore_item_not_const.stderr new file mode 100644 index 000000000..0bc7642dd --- /dev/null +++ b/src/test/ui/parser/underscore_item_not_const.stderr @@ -0,0 +1,74 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:3:8 + | +LL | static _: () = (); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:4:8 + | +LL | struct _(); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:5:6 + | +LL | enum _ {} + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:6:4 + | +LL | fn _() {} + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:7:5 + | +LL | mod _ {} + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:8:6 + | +LL | type _ = (); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:9:5 + | +LL | use _; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:10:5 + | +LL | use _ as g; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:11:7 + | +LL | trait _ {} + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:12:7 + | +LL | trait _ = Copy; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:13:14 + | +LL | macro_rules! _ { () => {} } + | ^ expected identifier, found reserved identifier + +error: expected one of `!` or `::`, found reserved identifier `_` + --> $DIR/underscore_item_not_const.rs:14:7 + | +LL | union _ { f: u8 } + | ^ expected one of `!` or `::` + +error: aborting due to 12 previous errors + diff --git a/src/test/ui/parser/unicode-character-literal.fixed b/src/test/ui/parser/unicode-character-literal.fixed new file mode 100644 index 000000000..26ef5ffa1 --- /dev/null +++ b/src/test/ui/parser/unicode-character-literal.fixed @@ -0,0 +1,21 @@ +// Regression test for #88684: Improve diagnostics for combining marks +// in character literals. + +// run-rustfix + +fn main() { + let _spade = "♠️"; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _s = "ṩ̂̊"; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _a = 'Å'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `A` is followed by the combining mark `\u{30a}` + //~| HELP: consider using the normalized form `\u{c5}` of this character +} diff --git a/src/test/ui/parser/unicode-character-literal.rs b/src/test/ui/parser/unicode-character-literal.rs new file mode 100644 index 000000000..d331522c0 --- /dev/null +++ b/src/test/ui/parser/unicode-character-literal.rs @@ -0,0 +1,21 @@ +// Regression test for #88684: Improve diagnostics for combining marks +// in character literals. + +// run-rustfix + +fn main() { + let _spade = '♠️'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _s = 'ṩ̂̊'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _a = 'Å'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `A` is followed by the combining mark `\u{30a}` + //~| HELP: consider using the normalized form `\u{c5}` of this character +} diff --git a/src/test/ui/parser/unicode-character-literal.stderr b/src/test/ui/parser/unicode-character-literal.stderr new file mode 100644 index 000000000..5cd3bd0fe --- /dev/null +++ b/src/test/ui/parser/unicode-character-literal.stderr @@ -0,0 +1,48 @@ +error: character literal may only contain one codepoint + --> $DIR/unicode-character-literal.rs:7:18 + | +LL | let _spade = '♠️'; + | ^^^ + | +note: this `♠` is followed by the combining mark `\u{fe0f}` + --> $DIR/unicode-character-literal.rs:7:19 + | +LL | let _spade = '♠️'; + | ^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let _spade = "♠️"; + | ~~~ + +error: character literal may only contain one codepoint + --> $DIR/unicode-character-literal.rs:12:14 + | +LL | let _s = 'ṩ̂̊'; + | ^^^ + | +note: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}` + --> $DIR/unicode-character-literal.rs:12:15 + | +LL | let _s = 'ṩ̂̊'; + | ^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let _s = "ṩ̂̊"; + | ~~~ + +error: character literal may only contain one codepoint + --> $DIR/unicode-character-literal.rs:17:14 + | +LL | let _a = 'Å'; + | ^-^ + | | + | help: consider using the normalized form `\u{c5}` of this character: `Å` + | +note: this `A` is followed by the combining mark `\u{30a}` + --> $DIR/unicode-character-literal.rs:17:15 + | +LL | let _a = 'Å'; + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/unicode-chars.rs b/src/test/ui/parser/unicode-chars.rs new file mode 100644 index 000000000..89ae85ec9 --- /dev/null +++ b/src/test/ui/parser/unicode-chars.rs @@ -0,0 +1,5 @@ +fn main() { + let y = 0; + //~^ ERROR unknown start of token: \u{37e} + //~^^ HELP Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not +} diff --git a/src/test/ui/parser/unicode-chars.stderr b/src/test/ui/parser/unicode-chars.stderr new file mode 100644 index 000000000..0cfe9240e --- /dev/null +++ b/src/test/ui/parser/unicode-chars.stderr @@ -0,0 +1,13 @@ +error: unknown start of token: \u{37e} + --> $DIR/unicode-chars.rs:2:14 + | +LL | let y = 0; + | ^ + | +help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not + | +LL | let y = 0; + | ~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/unicode-control-codepoints.rs b/src/test/ui/parser/unicode-control-codepoints.rs new file mode 100644 index 000000000..5af0b585a --- /dev/null +++ b/src/test/ui/parser/unicode-control-codepoints.rs @@ -0,0 +1,39 @@ +fn main() { + // if access_level != "user" { // Check if admin + //~^ ERROR unicode codepoint changing visible direction of text present in comment + println!("us\u{202B}e\u{202A}r"); + println!("{:?}", r#"us\u{202B}e\u{202A}r"#); + println!("{:?}", b"us\u{202B}e\u{202A}r"); + //~^ ERROR unicode escape in byte string + //~| ERROR unicode escape in byte string + println!("{:?}", br##"us\u{202B}e\u{202A}r"##); + + println!("{:?}", "/* } if isAdmin begin admins only "); + //~^ ERROR unicode codepoint changing visible direction of text present in literal + + println!("{:?}", r##"/* } if isAdmin begin admins only "##); + //~^ ERROR unicode codepoint changing visible direction of text present in literal + println!("{:?}", b"/* } if isAdmin begin admins only "); + //~^ ERROR non-ASCII character in byte constant + //~| ERROR non-ASCII character in byte constant + //~| ERROR non-ASCII character in byte constant + //~| ERROR non-ASCII character in byte constant + println!("{:?}", br##"/* } if isAdmin begin admins only "##); + //~^ ERROR raw byte string must be ASCII + //~| ERROR raw byte string must be ASCII + //~| ERROR raw byte string must be ASCII + //~| ERROR raw byte string must be ASCII + println!("{:?}", ''); + //~^ ERROR unicode codepoint changing visible direction of text present in literal +} + +//"/* } if isAdmin begin admins only */" +//~^ ERROR unicode codepoint changing visible direction of text present in comment + +/** ''); */fn foo() {} +//~^ ERROR unicode codepoint changing visible direction of text present in doc comment + +/** + * + * ''); */fn bar() {} +//~^^^ ERROR unicode codepoint changing visible direction of text present in doc comment diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr new file mode 100644 index 000000000..71509fe41 --- /dev/null +++ b/src/test/ui/parser/unicode-control-codepoints.stderr @@ -0,0 +1,192 @@ +error: unicode escape in byte string + --> $DIR/unicode-control-codepoints.rs:6:26 + | +LL | println!("{:?}", b"us\u{202B}e\u{202A}r"); + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string + +error: unicode escape in byte string + --> $DIR/unicode-control-codepoints.rs:6:35 + | +LL | println!("{:?}", b"us\u{202B}e\u{202A}r"); + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string + +error: non-ASCII character in byte constant + --> $DIR/unicode-control-codepoints.rs:16:26 + | +LL | println!("{:?}", b"/* } if isAdmin begin admins only "); + | ^ byte constant must be ASCII but is '\u{202e}' + | +help: if you meant to use the UTF-8 encoding of '\u{202e}', use \xHH escapes + | +LL | println!("{:?}", b"/*\xE2\x80\xAE } if isAdmin begin admins only "); + | ~~~~~~~~~~~~ + +error: non-ASCII character in byte constant + --> $DIR/unicode-control-codepoints.rs:16:30 + | +LL | println!("{:?}", b"/* } if isAdmin begin admins only "); + | ^ byte constant must be ASCII but is '\u{2066}' + | +help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes + | +LL | println!("{:?}", b"/* } \xE2\x81\xA6if isAdmin begin admins only "); + | ~~~~~~~~~~~~ + +error: non-ASCII character in byte constant + --> $DIR/unicode-control-codepoints.rs:16:41 + | +LL | println!("{:?}", b"/* } if isAdmin begin admins only "); + | ^ byte constant must be ASCII but is '\u{2069}' + | +help: if you meant to use the UTF-8 encoding of '\u{2069}', use \xHH escapes + | +LL | println!("{:?}", b"/* } if isAdmin\xE2\x81\xA9 begin admins only "); + | ~~~~~~~~~~~~ + +error: non-ASCII character in byte constant + --> $DIR/unicode-control-codepoints.rs:16:43 + | +LL | println!("{:?}", b"/* } if isAdmin begin admins only "); + | ^ byte constant must be ASCII but is '\u{2066}' + | +help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes + | +LL | println!("{:?}", b"/* } if isAdmin \xE2\x81\xA6 begin admins only "); + | ~~~~~~~~~~~~ + +error: raw byte string must be ASCII + --> $DIR/unicode-control-codepoints.rs:21:29 + | +LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); + | ^ must be ASCII but is '\u{202e}' + +error: raw byte string must be ASCII + --> $DIR/unicode-control-codepoints.rs:21:33 + | +LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); + | ^ must be ASCII but is '\u{2066}' + +error: raw byte string must be ASCII + --> $DIR/unicode-control-codepoints.rs:21:44 + | +LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); + | ^ must be ASCII but is '\u{2069}' + +error: raw byte string must be ASCII + --> $DIR/unicode-control-codepoints.rs:21:46 + | +LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); + | ^ must be ASCII but is '\u{2066}' + +error: unicode codepoint changing visible direction of text present in comment + --> $DIR/unicode-control-codepoints.rs:2:5 + | +LL | // if access_level != "user" { // Check if admin + | ^^^^^^^^^^^^^^^^^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^ + | | || + | | |'\u{202a}' + | | '\u{202b}' + | this comment contains invisible unicode text flow control codepoints + | + = note: `#[deny(text_direction_codepoint_in_comment)]` on by default + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = help: if their presence wasn't intentional, you can remove them + +error: unicode codepoint changing visible direction of text present in comment + --> $DIR/unicode-control-codepoints.rs:30:1 + | +LL | //"/* } if isAdmin begin admins only */" + | ^^^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^ + | | | | || + | | | | |'\u{2066}' + | | | | '\u{2069}' + | | | '\u{2066}' + | | '\u{202e}' + | this comment contains invisible unicode text flow control codepoints + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = help: if their presence wasn't intentional, you can remove them + +error: unicode codepoint changing visible direction of text present in literal + --> $DIR/unicode-control-codepoints.rs:11:22 + | +LL | println!("{:?}", "/* } if isAdmin begin admins only "); + | ^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^ + | | | | || + | | | | |'\u{2066}' + | | | | '\u{2069}' + | | | '\u{2066}' + | | '\u{202e}' + | this literal contains invisible unicode text flow control codepoints + | + = note: `#[deny(text_direction_codepoint_in_literal)]` on by default + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = help: if their presence wasn't intentional, you can remove them +help: if you want to keep them but make them visible in your source code, you can escape them + | +LL | println!("{:?}", "/*\u{202e} } \u{2066}if isAdmin\u{2069} \u{2066} begin admins only "); + | ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ + +error: unicode codepoint changing visible direction of text present in literal + --> $DIR/unicode-control-codepoints.rs:14:22 + | +LL | println!("{:?}", r##"/* } if isAdmin begin admins only "##); + | ^^^^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^ + | | | | || + | | | | |'\u{2066}' + | | | | '\u{2069}' + | | | '\u{2066}' + | | '\u{202e}' + | this literal contains invisible unicode text flow control codepoints + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = help: if their presence wasn't intentional, you can remove them +help: if you want to keep them but make them visible in your source code, you can escape them + | +LL | println!("{:?}", r##"/*\u{202e} } \u{2066}if isAdmin\u{2069} \u{2066} begin admins only "##); + | ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ + +error: unicode codepoint changing visible direction of text present in literal + --> $DIR/unicode-control-codepoints.rs:26:22 + | +LL | println!("{:?}", ''); + | ^- + | || + | |'\u{202e}' + | this literal contains an invisible unicode text flow control codepoint + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = help: if their presence wasn't intentional, you can remove them +help: if you want to keep them but make them visible in your source code, you can escape them + | +LL | println!("{:?}", '\u{202e}'); + | ~~~~~~~~ + +error: unicode codepoint changing visible direction of text present in doc comment + --> $DIR/unicode-control-codepoints.rs:33:1 + | +LL | /** ''); */fn foo() {} + | ^^^^^^^^^^^^ this doc comment contains an invisible unicode text flow control codepoint + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = note: if their presence wasn't intentional, you can remove them + = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}' + +error: unicode codepoint changing visible direction of text present in doc comment + --> $DIR/unicode-control-codepoints.rs:36:1 + | +LL | / /** +LL | | * +LL | | * ''); */fn bar() {} + | |___________^ this doc comment contains an invisible unicode text flow control codepoint + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = note: if their presence wasn't intentional, you can remove them + = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}' + +error: aborting due to 17 previous errors + diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs new file mode 100644 index 000000000..868d2b227 --- /dev/null +++ b/src/test/ui/parser/unicode-quote-chars.rs @@ -0,0 +1,8 @@ +fn main() { + println!(“hello world”); + //~^ ERROR unknown start of token: \u{201c} + //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not + //~^^^ ERROR unknown start of token: \u{201d} + //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not + //~^^^^^ ERROR expected `,`, found `world` +} diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr new file mode 100644 index 000000000..092abeb53 --- /dev/null +++ b/src/test/ui/parser/unicode-quote-chars.stderr @@ -0,0 +1,30 @@ +error: unknown start of token: \u{201c} + --> $DIR/unicode-quote-chars.rs:2:14 + | +LL | println!(“hello world”); + | ^ + | +help: Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not + | +LL | println!("hello world"); + | ~~~~~~~~~~~~~ + +error: unknown start of token: \u{201d} + --> $DIR/unicode-quote-chars.rs:2:26 + | +LL | println!(“hello world”); + | ^ + | +help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not + | +LL | println!(“hello world"); + | ~ + +error: expected `,`, found `world` + --> $DIR/unicode-quote-chars.rs:2:21 + | +LL | println!(“hello world”); + | ^^^^^ expected `,` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs new file mode 100644 index 000000000..f56013266 --- /dev/null +++ b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs @@ -0,0 +1,11 @@ +struct S { + x: usize, + y: usize, +} + +fn main() { + S { x: 4, + y: 5 }; +} + +fn foo() { //~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr new file mode 100644 index 000000000..430a13e6e --- /dev/null +++ b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr @@ -0,0 +1,8 @@ +error: this file contains an unclosed delimiter + --> $DIR/unmatched-delimiter-at-end-of-file.rs:11:63 + | +LL | fn foo() { + | - unclosed delimiter ^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/unmatched-langle-1.rs b/src/test/ui/parser/unmatched-langle-1.rs new file mode 100644 index 000000000..fdf2ae398 --- /dev/null +++ b/src/test/ui/parser/unmatched-langle-1.rs @@ -0,0 +1,9 @@ +// Check that a suggestion is issued if there are too many `<`s in a +// generic argument list, and that the parser recovers properly. + +fn main() { + foo::<<<<Ty<i32>>(); + //~^ ERROR: unmatched angle brackets + //~| ERROR: cannot find function `foo` in this scope [E0425] + //~| ERROR: cannot find type `Ty` in this scope [E0412] +} diff --git a/src/test/ui/parser/unmatched-langle-1.stderr b/src/test/ui/parser/unmatched-langle-1.stderr new file mode 100644 index 000000000..c8072b4c5 --- /dev/null +++ b/src/test/ui/parser/unmatched-langle-1.stderr @@ -0,0 +1,22 @@ +error: unmatched angle brackets + --> $DIR/unmatched-langle-1.rs:5:10 + | +LL | foo::<<<<Ty<i32>>(); + | ^^^ help: remove extra angle brackets + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/unmatched-langle-1.rs:5:5 + | +LL | foo::<<<<Ty<i32>>(); + | ^^^ not found in this scope + +error[E0412]: cannot find type `Ty` in this scope + --> $DIR/unmatched-langle-1.rs:5:14 + | +LL | foo::<<<<Ty<i32>>(); + | ^^ not found in this scope + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/parser/unmatched-langle-2.rs b/src/test/ui/parser/unmatched-langle-2.rs new file mode 100644 index 000000000..8de0d7d89 --- /dev/null +++ b/src/test/ui/parser/unmatched-langle-2.rs @@ -0,0 +1,15 @@ +// When there are too many opening `<`s, the compiler would previously +// suggest nonsense if the `<`s were interspersed with other tokens: +// +// error: unmatched angle brackets +// --> unmatched-langle.rs:2:10 +// | +// 2 | foo::<Ty<<<i32>(); +// | ^^^ help: remove extra angle brackets +// +// This test makes sure that this is no longer happening. + +fn main() { + foo::<Ty<<<i32>(); + //~^ ERROR: expected `::`, found `(` +} diff --git a/src/test/ui/parser/unmatched-langle-2.stderr b/src/test/ui/parser/unmatched-langle-2.stderr new file mode 100644 index 000000000..773bb33d8 --- /dev/null +++ b/src/test/ui/parser/unmatched-langle-2.stderr @@ -0,0 +1,8 @@ +error: expected `::`, found `(` + --> $DIR/unmatched-langle-2.rs:13:20 + | +LL | foo::<Ty<<<i32>(); + | ^ expected `::` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/unsafe-foreign-mod-2.rs b/src/test/ui/parser/unsafe-foreign-mod-2.rs new file mode 100644 index 000000000..77856fb67 --- /dev/null +++ b/src/test/ui/parser/unsafe-foreign-mod-2.rs @@ -0,0 +1,8 @@ +extern "C" unsafe { + //~^ ERROR expected `{`, found keyword `unsafe` + //~| ERROR extern block cannot be declared unsafe + unsafe fn foo(); + //~^ ERROR functions in `extern` blocks cannot have qualifiers +} + +fn main() {} diff --git a/src/test/ui/parser/unsafe-foreign-mod-2.stderr b/src/test/ui/parser/unsafe-foreign-mod-2.stderr new file mode 100644 index 000000000..7cc2de141 --- /dev/null +++ b/src/test/ui/parser/unsafe-foreign-mod-2.stderr @@ -0,0 +1,28 @@ +error: expected `{`, found keyword `unsafe` + --> $DIR/unsafe-foreign-mod-2.rs:1:12 + | +LL | extern "C" unsafe { + | ^^^^^^ expected `{` + +error: extern block cannot be declared unsafe + --> $DIR/unsafe-foreign-mod-2.rs:1:12 + | +LL | extern "C" unsafe { + | ^^^^^^ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/unsafe-foreign-mod-2.rs:4:15 + | +LL | extern "C" unsafe { + | ----------------- in this `extern` block +... +LL | unsafe fn foo(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn foo(); + | ~~ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/unsafe-foreign-mod.rs b/src/test/ui/parser/unsafe-foreign-mod.rs new file mode 100644 index 000000000..eab134a4a --- /dev/null +++ b/src/test/ui/parser/unsafe-foreign-mod.rs @@ -0,0 +1,5 @@ +unsafe extern "C" { + //~^ ERROR extern block cannot be declared unsafe +} + +fn main() {} diff --git a/src/test/ui/parser/unsafe-foreign-mod.stderr b/src/test/ui/parser/unsafe-foreign-mod.stderr new file mode 100644 index 000000000..4acf72c5d --- /dev/null +++ b/src/test/ui/parser/unsafe-foreign-mod.stderr @@ -0,0 +1,8 @@ +error: extern block cannot be declared unsafe + --> $DIR/unsafe-foreign-mod.rs:1:1 + | +LL | unsafe extern "C" { + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/unsafe-mod.rs b/src/test/ui/parser/unsafe-mod.rs new file mode 100644 index 000000000..7916d878e --- /dev/null +++ b/src/test/ui/parser/unsafe-mod.rs @@ -0,0 +1,9 @@ +unsafe mod m { + //~^ ERROR module cannot be declared unsafe +} + +unsafe mod n; +//~^ ERROR module cannot be declared unsafe +//~^^ ERROR file not found for module `n` + +fn main() {} diff --git a/src/test/ui/parser/unsafe-mod.stderr b/src/test/ui/parser/unsafe-mod.stderr new file mode 100644 index 000000000..dac6e7a35 --- /dev/null +++ b/src/test/ui/parser/unsafe-mod.stderr @@ -0,0 +1,23 @@ +error[E0583]: file not found for module `n` + --> $DIR/unsafe-mod.rs:5:1 + | +LL | unsafe mod n; + | ^^^^^^^^^^^^^ + | + = help: to create the module `n`, create file "$DIR/n.rs" or "$DIR/n/mod.rs" + +error: module cannot be declared unsafe + --> $DIR/unsafe-mod.rs:1:1 + | +LL | unsafe mod m { + | ^^^^^^ + +error: module cannot be declared unsafe + --> $DIR/unsafe-mod.rs:5:1 + | +LL | unsafe mod n; + | ^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0583`. diff --git a/src/test/ui/parser/unsized.rs b/src/test/ui/parser/unsized.rs new file mode 100644 index 000000000..e7fd7a196 --- /dev/null +++ b/src/test/ui/parser/unsized.rs @@ -0,0 +1,7 @@ +// Test syntax checks for `type` keyword. + +struct S1 for type; +//~^ ERROR expected `where`, `{`, `(`, or `;` after struct name, found keyword `for` + +pub fn main() { +} diff --git a/src/test/ui/parser/unsized.stderr b/src/test/ui/parser/unsized.stderr new file mode 100644 index 000000000..3d4ed526b --- /dev/null +++ b/src/test/ui/parser/unsized.stderr @@ -0,0 +1,8 @@ +error: expected `where`, `{`, `(`, or `;` after struct name, found keyword `for` + --> $DIR/unsized.rs:3:11 + | +LL | struct S1 for type; + | ^^^ expected `where`, `{`, `(`, or `;` after struct name + +error: aborting due to previous error + diff --git a/src/test/ui/parser/unsized2.rs b/src/test/ui/parser/unsized2.rs new file mode 100644 index 000000000..21370b329 --- /dev/null +++ b/src/test/ui/parser/unsized2.rs @@ -0,0 +1,7 @@ +// Test syntax checks for `type` keyword. + +fn f<X>() {} + +pub fn main() { + f<type>(); //~ ERROR expected expression, found keyword `type` +} diff --git a/src/test/ui/parser/unsized2.stderr b/src/test/ui/parser/unsized2.stderr new file mode 100644 index 000000000..17e39b292 --- /dev/null +++ b/src/test/ui/parser/unsized2.stderr @@ -0,0 +1,8 @@ +error: expected expression, found keyword `type` + --> $DIR/unsized2.rs:6:7 + | +LL | f<type>(); + | ^^^^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs new file mode 100644 index 000000000..b4bb48418 --- /dev/null +++ b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs @@ -0,0 +1,2 @@ +use std::any:: as foo; //~ ERROR expected identifier, found keyword `as` +//~^ ERROR: expected one of `::`, `;`, or `as`, found `foo` diff --git a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr new file mode 100644 index 000000000..192ab5eb7 --- /dev/null +++ b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr @@ -0,0 +1,14 @@ +error: expected identifier, found keyword `as` + --> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:16 + | +LL | use std::any:: as foo; + | ^^ expected identifier, found keyword + +error: expected one of `::`, `;`, or `as`, found `foo` + --> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:19 + | +LL | use std::any:: as foo; + | ^^^ expected one of `::`, `;`, or `as` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/use-ends-with-mod-sep.rs b/src/test/ui/parser/use-ends-with-mod-sep.rs new file mode 100644 index 000000000..ad8da4d18 --- /dev/null +++ b/src/test/ui/parser/use-ends-with-mod-sep.rs @@ -0,0 +1 @@ +use std::any::; //~ ERROR expected identifier, found `;` diff --git a/src/test/ui/parser/use-ends-with-mod-sep.stderr b/src/test/ui/parser/use-ends-with-mod-sep.stderr new file mode 100644 index 000000000..bd0d881a0 --- /dev/null +++ b/src/test/ui/parser/use-ends-with-mod-sep.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `;` + --> $DIR/use-ends-with-mod-sep.rs:1:15 + | +LL | use std::any::; + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/use-unclosed-brace.rs b/src/test/ui/parser/use-unclosed-brace.rs new file mode 100644 index 000000000..41742f37f --- /dev/null +++ b/src/test/ui/parser/use-unclosed-brace.rs @@ -0,0 +1,12 @@ +// error-pattern: expected one of `,`, `::`, `as`, or `}`, found `;` +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected item, found `}` +use foo::{bar, baz; + +use std::fmt::Display; + +mod bar { } + +mod baz { } + +fn main() {} diff --git a/src/test/ui/parser/use-unclosed-brace.stderr b/src/test/ui/parser/use-unclosed-brace.stderr new file mode 100644 index 000000000..438fe9c47 --- /dev/null +++ b/src/test/ui/parser/use-unclosed-brace.stderr @@ -0,0 +1,27 @@ +error: this file contains an unclosed delimiter + --> $DIR/use-unclosed-brace.rs:12:14 + | +LL | use foo::{bar, baz; + | - unclosed delimiter +... +LL | fn main() {} + | ^ + +error: expected one of `,`, `::`, `as`, or `}`, found `;` + --> $DIR/use-unclosed-brace.rs:4:10 + | +LL | use foo::{bar, baz; + | ^ ^ + | | | + | | expected one of `,`, `::`, `as`, or `}` + | | help: `}` may belong here + | unclosed delimiter + +error: expected item, found `}` + --> $DIR/use-unclosed-brace.rs:12:14 + | +LL | fn main() {} + | ^ expected item + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/utf16-be-without-bom.rs b/src/test/ui/parser/utf16-be-without-bom.rs Binary files differnew file mode 100644 index 000000000..22aa19717 --- /dev/null +++ b/src/test/ui/parser/utf16-be-without-bom.rs diff --git a/src/test/ui/parser/utf16-be-without-bom.stderr b/src/test/ui/parser/utf16-be-without-bom.stderr Binary files differnew file mode 100644 index 000000000..768d2c531 --- /dev/null +++ b/src/test/ui/parser/utf16-be-without-bom.stderr diff --git a/src/test/ui/parser/utf16-le-without-bom.rs b/src/test/ui/parser/utf16-le-without-bom.rs Binary files differnew file mode 100644 index 000000000..3c1049929 --- /dev/null +++ b/src/test/ui/parser/utf16-le-without-bom.rs diff --git a/src/test/ui/parser/utf16-le-without-bom.stderr b/src/test/ui/parser/utf16-le-without-bom.stderr Binary files differnew file mode 100644 index 000000000..4f4b91e39 --- /dev/null +++ b/src/test/ui/parser/utf16-le-without-bom.stderr diff --git a/src/test/ui/parser/utf8_idents-rpass.rs b/src/test/ui/parser/utf8_idents-rpass.rs new file mode 100644 index 000000000..206744a58 --- /dev/null +++ b/src/test/ui/parser/utf8_idents-rpass.rs @@ -0,0 +1,39 @@ +// run-pass +// +#![allow(non_snake_case)] + +pub fn main() { + let ε = 0.00001f64; + let Π = 3.14f64; + let लंच = Π * Π + 1.54; + assert!(((लंच - 1.54) - (Π * Π)).abs() < ε); + assert_eq!(საჭმელად_გემრიელი_სადილი(), 0); +} + +fn საჭმელად_გემრიელი_სადილი() -> isize { + + // Lunch in several languages. + + let ランチ = 10; + let 午餐 = 10; + + let ארוחת_צהריי = 10; + let غداء = 10_usize; + let լանչ = 10; + let обед = 10; + let абед = 10; + let μεσημεριανό = 10; + let hádegismatur = 10; + let ручек = 10; + + let ăn_trưa = 10; + let อาหารกลางวัน = 10; + + // Lunchy arithmetic, mm. + + assert_eq!(hádegismatur * ручек * обед, 1000); + assert_eq!(10, ארוחת_צהריי); + assert_eq!(ランチ + 午餐 + μεσημεριανό, 30); + assert_eq!(ăn_trưa + อาหารกลางวัน, 20); + return (абед + լանչ) >> غداء; +} diff --git a/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs new file mode 100644 index 000000000..9eeee195e --- /dev/null +++ b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs @@ -0,0 +1,9 @@ +fn f1<'a>(x: u8, y: &'a ...) {} +//~^ ERROR C-variadic type `...` may not be nested inside another type + +fn f2<'a>(x: u8, y: Vec<&'a ...>) {} +//~^ ERROR C-variadic type `...` may not be nested inside another type + +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr new file mode 100644 index 000000000..8b9d676a4 --- /dev/null +++ b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr @@ -0,0 +1,24 @@ +error[E0743]: C-variadic type `...` may not be nested inside another type + --> $DIR/variadic-ffi-nested-syntactic-fail.rs:1:25 + | +LL | fn f1<'a>(x: u8, y: &'a ...) {} + | ^^^ + +error[E0743]: C-variadic type `...` may not be nested inside another type + --> $DIR/variadic-ffi-nested-syntactic-fail.rs:4:29 + | +LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {} + | ^^^ + +error[E0308]: mismatched types + --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0743. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs new file mode 100644 index 000000000..0b61e267d --- /dev/null +++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -0,0 +1,77 @@ +#![feature(c_variadic)] +#![allow(anonymous_parameters)] + +fn main() {} + +fn f1_1(x: isize, ...) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + +fn f1_2(...) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic +//~| ERROR C-variadic function must be declared with at least one named argument + +extern "C" fn f2_1(x: isize, ...) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + +extern "C" fn f2_2(...) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic +//~| ERROR C-variadic function must be declared with at least one named argument + +extern "C" fn f2_3(..., x: isize) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic +//~| ERROR `...` must be the last argument of a C-variadic function + +extern "C" fn f3_1(x: isize, ...) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + +extern "C" fn f3_2(...) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic +//~| ERROR C-variadic function must be declared with at least one named argument + +extern "C" fn f3_3(..., x: isize) {} +//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic +//~| ERROR `...` must be the last argument of a C-variadic function + +extern "C" { + fn e_f1(...); + //~^ ERROR C-variadic function must be declared with at least one named argument + fn e_f2(..., x: isize); +//~^ ERROR `...` must be the last argument of a C-variadic function +} + +struct X; + +impl X { + fn i_f1(x: isize, ...) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + fn i_f2(...) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR C-variadic function must be declared with at least one named argument + fn i_f3(..., x: isize, ...) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR `...` must be the last argument of a C-variadic function + fn i_f4(..., x: isize, ...) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR `...` must be the last argument of a C-variadic function +} + +trait T { + fn t_f1(x: isize, ...) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + fn t_f2(x: isize, ...); + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + fn t_f3(...) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR C-variadic function must be declared with at least one named argument + fn t_f4(...); + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR C-variadic function must be declared with at least one named argument + fn t_f5(..., x: isize) {} + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR `...` must be the last argument of a C-variadic function + fn t_f6(..., x: isize); + //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic + //~| ERROR `...` must be the last argument of a C-variadic function +} diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr new file mode 100644 index 000000000..f1cbbb279 --- /dev/null +++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -0,0 +1,206 @@ +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 + | +LL | fn f1_1(x: isize, ...) {} + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 + | +LL | fn f1_2(...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 + | +LL | fn f1_2(...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:13:30 + | +LL | extern "C" fn f2_1(x: isize, ...) {} + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20 + | +LL | extern "C" fn f2_2(...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20 + | +LL | extern "C" fn f2_2(...) {} + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 + | +LL | extern "C" fn f2_3(..., x: isize) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 + | +LL | extern "C" fn f2_3(..., x: isize) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 + | +LL | extern "C" fn f3_1(x: isize, ...) {} + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 + | +LL | extern "C" fn f3_2(...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 + | +LL | extern "C" fn f3_2(...) {} + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 + | +LL | extern "C" fn f3_3(..., x: isize) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 + | +LL | extern "C" fn f3_3(..., x: isize) {} + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:13 + | +LL | fn e_f1(...); + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:38:13 + | +LL | fn e_f2(..., x: isize); + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:45:23 + | +LL | fn i_f1(x: isize, ...) {} + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13 + | +LL | fn i_f2(...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13 + | +LL | fn i_f2(...) {} + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13 + | +LL | fn i_f3(..., x: isize, ...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13 + | +LL | fn i_f3(..., x: isize, ...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:50:28 + | +LL | fn i_f3(..., x: isize, ...) {} + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:54:13 + | +LL | fn i_f4(..., x: isize, ...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:54:13 + | +LL | fn i_f4(..., x: isize, ...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:54:28 + | +LL | fn i_f4(..., x: isize, ...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:61:23 + | +LL | fn t_f1(x: isize, ...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:63:23 + | +LL | fn t_f2(x: isize, ...); + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:65:13 + | +LL | fn t_f3(...) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:65:13 + | +LL | fn t_f3(...) {} + | ^^^ + +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-semantic-restrictions.rs:68:13 + | +LL | fn t_f4(...); + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:68:13 + | +LL | fn t_f4(...); + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:71:13 + | +LL | fn t_f5(..., x: isize) {} + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:71:13 + | +LL | fn t_f5(..., x: isize) {} + | ^^^ + +error: `...` must be the last argument of a C-variadic function + --> $DIR/variadic-ffi-semantic-restrictions.rs:74:13 + | +LL | fn t_f6(..., x: isize); + | ^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:74:13 + | +LL | fn t_f6(..., x: isize); + | ^^^ + +error: aborting due to 34 previous errors + diff --git a/src/test/ui/parser/variadic-ffi-syntactic-pass.rs b/src/test/ui/parser/variadic-ffi-syntactic-pass.rs new file mode 100644 index 000000000..3875d6af1 --- /dev/null +++ b/src/test/ui/parser/variadic-ffi-syntactic-pass.rs @@ -0,0 +1,53 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn f1_1(x: isize, ...) {} + +#[cfg(FALSE)] +fn f1_2(...) {} + +#[cfg(FALSE)] +extern "C" fn f2_1(x: isize, ...) {} + +#[cfg(FALSE)] +extern "C" fn f2_2(...) {} + +#[cfg(FALSE)] +extern "C" fn f2_3(..., x: isize) {} + +#[cfg(FALSE)] +extern fn f3_1(x: isize, ...) {} + +#[cfg(FALSE)] +extern fn f3_2(...) {} + +#[cfg(FALSE)] +extern fn f3_3(..., x: isize) {} + +#[cfg(FALSE)] +extern { + fn e_f1(...); + fn e_f2(..., x: isize); +} + +struct X; + +#[cfg(FALSE)] +impl X { + fn i_f1(x: isize, ...) {} + fn i_f2(...) {} + fn i_f3(..., x: isize, ...) {} + fn i_f4(..., x: isize, ...) {} +} + +#[cfg(FALSE)] +trait T { + fn t_f1(x: isize, ...) {} + fn t_f2(x: isize, ...); + fn t_f3(...) {} + fn t_f4(...); + fn t_f5(..., x: isize) {} + fn t_f6(..., x: isize); +} diff --git a/src/test/ui/parser/virtual-structs.rs b/src/test/ui/parser/virtual-structs.rs new file mode 100644 index 000000000..ce57a3454 --- /dev/null +++ b/src/test/ui/parser/virtual-structs.rs @@ -0,0 +1,10 @@ +// Test diagnostics for the removed struct inheritance feature. + +virtual struct SuperStruct { +//~^ ERROR expected item, found reserved keyword `virtual` + f1: isize, +} + +struct Struct : SuperStruct; + +pub fn main() {} diff --git a/src/test/ui/parser/virtual-structs.stderr b/src/test/ui/parser/virtual-structs.stderr new file mode 100644 index 000000000..a5211d83f --- /dev/null +++ b/src/test/ui/parser/virtual-structs.stderr @@ -0,0 +1,8 @@ +error: expected item, found reserved keyword `virtual` + --> $DIR/virtual-structs.rs:3:1 + | +LL | virtual struct SuperStruct { + | ^^^^^^^ expected item + +error: aborting due to previous error + diff --git a/src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs new file mode 100644 index 000000000..e80db5372 --- /dev/null +++ b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs @@ -0,0 +1,15 @@ +// Empty predicate list is OK +fn equal1<T>(_: &T, _: &T) -> bool where { + true +} + +// Empty bound list is OK +fn equal2<T>(_: &T, _: &T) -> bool where T: { + true +} + +fn foo<'a>() where 'a {} +//~^ ERROR expected `:`, found `{` + +fn main() { +} diff --git a/src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr new file mode 100644 index 000000000..b80b0a409 --- /dev/null +++ b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr @@ -0,0 +1,8 @@ +error: expected `:`, found `{` + --> $DIR/where-clauses-no-bounds-or-predicates.rs:11:23 + | +LL | fn foo<'a>() where 'a {} + | ^ expected `:` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/where_with_bound.rs b/src/test/ui/parser/where_with_bound.rs new file mode 100644 index 000000000..3ca45f188 --- /dev/null +++ b/src/test/ui/parser/where_with_bound.rs @@ -0,0 +1,5 @@ +fn foo<T>() where <T>::Item: ToString, T: Iterator { } +//~^ ERROR generic parameters on `where` clauses are reserved for future use +//~| ERROR cannot find type `Item` in the crate root + +fn main() {} diff --git a/src/test/ui/parser/where_with_bound.stderr b/src/test/ui/parser/where_with_bound.stderr new file mode 100644 index 000000000..ff98b3f5f --- /dev/null +++ b/src/test/ui/parser/where_with_bound.stderr @@ -0,0 +1,15 @@ +error: generic parameters on `where` clauses are reserved for future use + --> $DIR/where_with_bound.rs:1:19 + | +LL | fn foo<T>() where <T>::Item: ToString, T: Iterator { } + | ^^^ currently unsupported + +error[E0412]: cannot find type `Item` in the crate root + --> $DIR/where_with_bound.rs:1:24 + | +LL | fn foo<T>() where <T>::Item: ToString, T: Iterator { } + | ^^^^ not found in the crate root + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/parser/while-if-let-without-body.rs b/src/test/ui/parser/while-if-let-without-body.rs new file mode 100644 index 000000000..063c0145c --- /dev/null +++ b/src/test/ui/parser/while-if-let-without-body.rs @@ -0,0 +1,13 @@ +fn main() { + let container = vec![Some(1), Some(2), None]; + + let mut i = 0; + while if let Some(thing) = container.get(i) { + //~^ NOTE while parsing the body of this `while` expression + //~| NOTE this `while` condition successfully parsed + println!("{:?}", thing); + i += 1; + } +} +//~^ ERROR expected `{`, found `}` +//~| NOTE expected `{` diff --git a/src/test/ui/parser/while-if-let-without-body.stderr b/src/test/ui/parser/while-if-let-without-body.stderr new file mode 100644 index 000000000..2dac45c11 --- /dev/null +++ b/src/test/ui/parser/while-if-let-without-body.stderr @@ -0,0 +1,18 @@ +error: expected `{`, found `}` + --> $DIR/while-if-let-without-body.rs:11:1 + | +LL | while if let Some(thing) = container.get(i) { + | _____-----_- + | | | + | | while parsing the body of this `while` expression +LL | | +LL | | +LL | | println!("{:?}", thing); +LL | | i += 1; +LL | | } + | |_____- this `while` condition successfully parsed +LL | } + | ^ expected `{` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.rs b/src/test/ui/parser/wrong-escape-of-curly-braces.rs new file mode 100644 index 000000000..8e5258acd --- /dev/null +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.rs @@ -0,0 +1,8 @@ +fn main() { + let ok = "{{everything fine}}"; + let bad = "\{it is wrong\}"; + //~^ ERROR unknown character escape: `{` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~| ERROR unknown character escape: `}` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` +} diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr new file mode 100644 index 000000000..ff1a2fb0f --- /dev/null +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr @@ -0,0 +1,18 @@ +error: unknown character escape: `{` + --> $DIR/wrong-escape-of-curly-braces.rs:3:17 + | +LL | let bad = "\{it is wrong\}"; + | ^ unknown character escape + | + = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` + +error: unknown character escape: `}` + --> $DIR/wrong-escape-of-curly-braces.rs:3:30 + | +LL | let bad = "\{it is wrong\}"; + | ^ unknown character escape + | + = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` + +error: aborting due to 2 previous errors + |