diff options
| author | bors <bors@rust-lang.org> | 2019-12-21 11:05:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-12-21 11:05:03 +0000 |
| commit | c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06 (patch) | |
| tree | 073a8038727414aed13f54622fce43ca63990ca6 /src/test/ui/parser | |
| parent | 9ff30a7810c586819a78188c173a7b74adbb9730 (diff) | |
| parent | 621661f8a63f2118f3add5c3d686d9a2b6f62e5e (diff) | |
| download | rust-c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06.tar.gz rust-c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06.zip | |
Auto merge of #66994 - Centril:stmt-polish, r=estebank
refactor expr & stmt parsing + improve recovery
Summary of important changes (best read commit-by-commit, ignoring whitespace changes):
- `AttrVec` is introduces as an alias for `ThinVec<Attribute>`
- `parse_expr_bottom` and `parse_stmt` are thoroughly refactored.
- Extract diagnostics logic for `vec![...]` in a pattern context.
- Recovery is added for `do catch { ... }`
- Recovery is added for `'label: non_block_expr`
- Recovery is added for `var $local`, `auto $local`, and `mut $local`. Fixes #65257.
- Recovery is added for `e1 and e2` and `e1 or e2`.
- ~~`macro_legacy_warnings` is turned into an error (has been a warning for 3 years!)~~
- Fixes #63396 by forward-porting #64105 which now works thanks to added recovery.
- `ui-fulldeps/ast_stmt_expr_attr.rs` is turned into UI and pretty tests.
- Recovery is fixed for `#[attr] if expr {}`
r? @estebank
Diffstat (limited to 'src/test/ui/parser')
| -rw-r--r-- | src/test/ui/parser/attr-stmt-expr-attr-bad-2.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/parser/attr-stmt-expr-attr-bad-2.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/parser/attr-stmt-expr-attr-bad-3.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/parser/attr-stmt-expr-attr-bad-3.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/parser/attr-stmt-expr-attr-bad.rs | 107 | ||||
| -rw-r--r-- | src/test/ui/parser/attr-stmt-expr-attr-bad.stderr | 390 | ||||
| -rw-r--r-- | src/test/ui/parser/do-catch-suggests-try.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/parser/do-catch-suggests-try.stderr | 17 | ||||
| -rw-r--r-- | src/test/ui/parser/issue-65257-invalid-var-decl-recovery.rs | 21 | ||||
| -rw-r--r-- | src/test/ui/parser/issue-65257-invalid-var-decl-recovery.stderr | 67 | ||||
| -rw-r--r-- | src/test/ui/parser/recover-labeled-non-block-expr.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/parser/recover-labeled-non-block-expr.stderr | 17 | ||||
| -rw-r--r-- | src/test/ui/parser/recovery-attr-on-if.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/parser/recovery-attr-on-if.stderr | 35 | ||||
| -rw-r--r-- | src/test/ui/parser/stmt_expr_attrs_placement.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/parser/stmt_expr_attrs_placement.stderr | 10 |
16 files changed, 722 insertions, 5 deletions
diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad-2.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad-2.rs new file mode 100644 index 00000000000..e5ac59ae463 --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad-2.rs @@ -0,0 +1,2 @@ +#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } +//~^ ERROR unexpected token: `#` diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad-2.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad-2.stderr new file mode 100644 index 00000000000..ca1043250ba --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad-2.stderr @@ -0,0 +1,8 @@ +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad-2.rs:1:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad-3.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad-3.rs new file mode 100644 index 00000000000..7dc71af52f4 --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad-3.rs @@ -0,0 +1,2 @@ +#[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } +//~^ ERROR unexpected token: `#` diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad-3.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad-3.stderr new file mode 100644 index 00000000000..ab9366d042a --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad-3.stderr @@ -0,0 +1,8 @@ +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad-3.rs:1:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } + | ^ + +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 00000000000..ef10010ed0e --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs @@ -0,0 +1,107 @@ +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 _ = #[attr] if 0 {}; } +//~^ ERROR attributes are not yet allowed on `if` expressions +#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } +//~^ ERROR expected `{`, found `#` +#[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 expected `{`, found `#` +#[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 attributes are not yet allowed on `if` expressions +//~| ERROR expected `{`, found `#` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } +//~^ ERROR expected `{`, found `#` +#[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 _ = #[attr] if let _ = 0 {}; } +//~^ ERROR attributes are not yet allowed on `if` expressions +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } +//~^ ERROR expected `{`, found `#` +#[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 expected `{`, found `#` +#[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 attributes are not yet allowed on `if` expressions +//~| ERROR expected `{`, found `#` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } +//~^ ERROR expected `{`, found `#` +#[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 `X..=` range patterns are not supported +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } +//~^ ERROR `X..=` range patterns are not supported +//~| 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 `X..=` range patterns are not supported +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` + +// 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] } } } 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 00000000000..9a0d3176714 --- /dev/null +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -0,0 +1,390 @@ +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:3: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: expected expression, found `]` + --> $DIR/attr-stmt-expr-attr-bad.rs:5:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = [#[attr]]; } + | ^ expected expression + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:7:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo#[attr](); } + | ^ expected one of 7 possible tokens + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:9: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: expected expression, found `)` + --> $DIR/attr-stmt-expr-attr-bad.rs:9: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:12: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: expected expression, found `)` + --> $DIR/attr-stmt-expr-attr-bad.rs:12: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:15: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. 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:17: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. 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. Outer attributes, like `#[test]`, annotate the item following them. + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:21:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } + | ^ expected one of 7 possible tokens + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:23: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. 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:25: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. 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: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. 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: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: expected expression, found `..` + --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } + | ^^ expected expression + +error: expected expression, found `..` + --> $DIR/attr-stmt-expr-attr-bad.rs:33: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:35: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. 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:37: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: attributes are not yet allowed on `if` expressions + --> $DIR/attr-stmt-expr-attr-bad.rs:39:32 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] if 0 {}; } + | ^^^^^^^ + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:41:37 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } + | -- ^ --- help: try placing this code inside a block: `{ {}; }` + | | | + | | expected `{` + | this `if` statement has a condition, but no block + +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. 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: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:47:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } + | ^ --- help: try placing this code inside a block: `{ {}; }` + | | + | expected `{` + +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. Outer attributes, like `#[test]`, annotate the item following them. + +error: attributes are not yet allowed on `if` expressions + --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } + | ^^^^^^^ + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } + | ^ -------- help: try placing this code inside a block: `{ if 0 {}; }` + | | + | expected `{` + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:54:50 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } + | -- ^ --- help: try placing this code inside a block: `{ {}; }` + | | | + | | expected `{` + | this `if` statement has a condition, but no block + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:56: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: attributes are not yet allowed on `if` expressions + --> $DIR/attr-stmt-expr-attr-bad.rs:58:32 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] if let _ = 0 {}; } + | ^^^^^^^ + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:60:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } + | -- ^ --- help: try placing this code inside a block: `{ {}; }` + | | | + | | expected `{` + | this `if` statement has a condition, but no block + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:62: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. 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:64:48 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:66:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } + | ^ --- help: try placing this code inside a block: `{ {}; }` + | | + | expected `{` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:68: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. Outer attributes, like `#[test]`, annotate the item following them. + +error: attributes are not yet allowed on `if` expressions + --> $DIR/attr-stmt-expr-attr-bad.rs:70:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } + | ^^^^^^^ + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:70:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } + | ^ ---------------- help: try placing this code inside a block: `{ if let _ = 0 {}; }` + | | + | expected `{` + +error: expected `{`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:73:66 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } + | -- ^ --- help: try placing this code inside a block: `{ {}; }` + | | | + | | expected `{` + | this `if` statement has a condition, but no block + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:75: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. 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] let _ = 0; } + | ------- ^^^^^^^^ not permitted following an outer attibute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. 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:80:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } + | ------- ^^^^^^^^ not permitted following an outer attibute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. 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:82:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } + | ------- ^^^^^^^^ not permitted following an outer attibute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. 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:84:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } + | ------- ^^^^^^^^ not permitted following an outer attibute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. 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:86:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } + | ------- ^^^^^^^^ not permitted following an outer attibute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + +error: `X..=` range patterns are not supported + --> $DIR/attr-stmt-expr-attr-bad.rs:92:34 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } + | ^^^^ help: try using the maximum value for the type: `0..=MAX` + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:92:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } + | ^ expected one of `=>`, `if`, or `|` + +error: `X..=` range patterns are not supported + --> $DIR/attr-stmt-expr-attr-bad.rs:95:34 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } + | ^^^^ help: try using the maximum value for the type: `0..=MAX` + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:95: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:98:39 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } + | ^ + +error: `X..=` range patterns are not supported + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } + | ^^^^ help: try using the maximum value for the type: `0..=MAX` + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:100:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } + | ^ expected one of `=>`, `if`, or `|` + +error: expected statement after outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:105:44 + | +LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } + | ^ + +error: aborting due to 52 previous errors + diff --git a/src/test/ui/parser/do-catch-suggests-try.rs b/src/test/ui/parser/do-catch-suggests-try.rs index d805ab75882..f64568d06e9 100644 --- a/src/test/ui/parser/do-catch-suggests-try.rs +++ b/src/test/ui/parser/do-catch-suggests-try.rs @@ -1,5 +1,10 @@ +#![feature(try_blocks)] + fn main() { let _: Option<()> = do catch {}; //~^ ERROR found removed `do catch` syntax - //~^^ HELP following RFC #2388, the new non-placeholder syntax is `try` + //~| 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 index e151d4cf8a6..cd8907b7eac 100644 --- a/src/test/ui/parser/do-catch-suggests-try.stderr +++ b/src/test/ui/parser/do-catch-suggests-try.stderr @@ -1,10 +1,19 @@ error: found removed `do catch` syntax - --> $DIR/do-catch-suggests-try.rs:2:25 + --> $DIR/do-catch-suggests-try.rs:4:25 | LL | let _: Option<()> = do catch {}; - | ^^ + | ^^^^^^^^ help: replace with the new syntax: `try` | - = help: following RFC #2388, the new non-placeholder syntax is `try` + = note: following RFC #2388, the new non-placeholder syntax is `try` -error: aborting due to previous error +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/issue-65257-invalid-var-decl-recovery.rs b/src/test/ui/parser/issue-65257-invalid-var-decl-recovery.rs new file mode 100644 index 00000000000..c1826f8caae --- /dev/null +++ b/src/test/ui/parser/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/issue-65257-invalid-var-decl-recovery.stderr b/src/test/ui/parser/issue-65257-invalid-var-decl-recovery.stderr new file mode 100644 index 00000000000..ad72dd30542 --- /dev/null +++ b/src/test/ui/parser/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/recover-labeled-non-block-expr.rs b/src/test/ui/parser/recover-labeled-non-block-expr.rs new file mode 100644 index 00000000000..be92170acf0 --- /dev/null +++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs @@ -0,0 +1,5 @@ +fn main() { + 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + + let _recovery_witness: () = 0; //~ ERROR mismatched types +} 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 00000000000..771a915288c --- /dev/null +++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr @@ -0,0 +1,17 @@ +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:2:13 + | +LL | 'label: 1 + 1; + | ^ expected `while`, `for`, `loop` or `{` after a label + +error[E0308]: mismatched types + --> $DIR/recover-labeled-non-block-expr.rs:4: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/recovery-attr-on-if.rs b/src/test/ui/parser/recovery-attr-on-if.rs new file mode 100644 index 00000000000..0d1f5be7b49 --- /dev/null +++ b/src/test/ui/parser/recovery-attr-on-if.rs @@ -0,0 +1,9 @@ +fn main() { + #[attr] if true {}; + //~^ ERROR cannot find attribute + //~| ERROR attributes are not yet allowed on `if` expressions + #[attr] if true {}; + //~^ ERROR cannot find attribute + //~| ERROR attributes are not yet allowed on `if` expressions + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/recovery-attr-on-if.stderr b/src/test/ui/parser/recovery-attr-on-if.stderr new file mode 100644 index 00000000000..a02846827c9 --- /dev/null +++ b/src/test/ui/parser/recovery-attr-on-if.stderr @@ -0,0 +1,35 @@ +error: attributes are not yet allowed on `if` expressions + --> $DIR/recovery-attr-on-if.rs:2:5 + | +LL | #[attr] if true {}; + | ^^^^^^^ + +error: attributes are not yet allowed on `if` expressions + --> $DIR/recovery-attr-on-if.rs:5:5 + | +LL | #[attr] if true {}; + | ^^^^^^^ + +error: cannot find attribute `attr` in this scope + --> $DIR/recovery-attr-on-if.rs:5:7 + | +LL | #[attr] if true {}; + | ^^^^ + +error: cannot find attribute `attr` in this scope + --> $DIR/recovery-attr-on-if.rs:2:7 + | +LL | #[attr] if true {}; + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/recovery-attr-on-if.rs:8:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. 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 00000000000..b8a794f4b92 --- /dev/null +++ b/src/test/ui/parser/stmt_expr_attrs_placement.rs @@ -0,0 +1,22 @@ +#![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); + + let c = { + #![allow(warnings)] + (#![allow(warnings)] 1, 2) + }; + + let d = { + #![allow(warnings)] + let e = (#![allow(warnings)] 1, 2); + e + }; +} 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 00000000000..1886a0f9ba0 --- /dev/null +++ b/src/test/ui/parser/stmt_expr_attrs_placement.stderr @@ -0,0 +1,10 @@ +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. Outer attributes, like `#[test]`, annotate the item following them. + +error: aborting due to previous error + |
