summaryrefslogtreecommitdiffstats
path: root/tests/ui/parser/attribute
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /tests/ui/parser/attribute
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/parser/attribute')
-rw-r--r--tests/ui/parser/attribute/attr-bad-meta-2.rs2
-rw-r--r--tests/ui/parser/attribute/attr-bad-meta-2.stderr8
-rw-r--r--tests/ui/parser/attribute/attr-bad-meta-3.rs2
-rw-r--r--tests/ui/parser/attribute/attr-bad-meta-3.stderr8
-rw-r--r--tests/ui/parser/attribute/attr-bad-meta.rs2
-rw-r--r--tests/ui/parser/attribute/attr-bad-meta.stderr8
-rw-r--r--tests/ui/parser/attribute/attr-before-eof.rs3
-rw-r--r--tests/ui/parser/attribute/attr-before-eof.stderr8
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-fn.rs8
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-fn.stderr8
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-mod.rs6
-rw-r--r--tests/ui/parser/attribute/attr-dangling-in-mod.stderr8
-rw-r--r--tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs108
-rw-r--r--tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr446
-rw-r--r--tests/ui/parser/attribute/attr-with-a-semicolon.rs4
-rw-r--r--tests/ui/parser/attribute/attr-with-a-semicolon.stderr14
-rw-r--r--tests/ui/parser/attribute/attr.rs6
-rw-r--r--tests/ui/parser/attribute/attr.stderr17
-rw-r--r--tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs3
-rw-r--r--tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr8
-rw-r--r--tests/ui/parser/attribute/attrs-after-extern-mod.rs7
-rw-r--r--tests/ui/parser/attribute/attrs-after-extern-mod.stderr12
22 files changed, 696 insertions, 0 deletions
diff --git a/tests/ui/parser/attribute/attr-bad-meta-2.rs b/tests/ui/parser/attribute/attr-bad-meta-2.rs
new file mode 100644
index 000000000..db612ed88
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-bad-meta-2.rs
@@ -0,0 +1,2 @@
+#[path =] //~ ERROR expected expression, found `]`
+mod m {}
diff --git a/tests/ui/parser/attribute/attr-bad-meta-2.stderr b/tests/ui/parser/attribute/attr-bad-meta-2.stderr
new file mode 100644
index 000000000..6fc6fb665
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr-bad-meta-3.rs b/tests/ui/parser/attribute/attr-bad-meta-3.rs
new file mode 100644
index 000000000..b51e9f221
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-bad-meta-3.rs
@@ -0,0 +1,2 @@
+#[path() token] //~ ERROR expected `]`, found `token`
+mod m {}
diff --git a/tests/ui/parser/attribute/attr-bad-meta-3.stderr b/tests/ui/parser/attribute/attr-bad-meta-3.stderr
new file mode 100644
index 000000000..4fa420c79
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr-bad-meta.rs b/tests/ui/parser/attribute/attr-bad-meta.rs
new file mode 100644
index 000000000..8001977f5
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-bad-meta.rs
@@ -0,0 +1,2 @@
+#[path*] //~ ERROR expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*`
+mod m {}
diff --git a/tests/ui/parser/attribute/attr-bad-meta.stderr b/tests/ui/parser/attribute/attr-bad-meta.stderr
new file mode 100644
index 000000000..8d65c423c
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr-before-eof.rs b/tests/ui/parser/attribute/attr-before-eof.rs
new file mode 100644
index 000000000..6af1783e6
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-before-eof.rs
@@ -0,0 +1,3 @@
+fn main() {}
+
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/tests/ui/parser/attribute/attr-before-eof.stderr b/tests/ui/parser/attribute/attr-before-eof.stderr
new file mode 100644
index 000000000..a2acb9437
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr-dangling-in-fn.rs b/tests/ui/parser/attribute/attr-dangling-in-fn.rs
new file mode 100644
index 000000000..c7c45bafb
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-dangling-in-fn.rs
@@ -0,0 +1,8 @@
+// error-pattern:expected statement
+
+fn f() {
+ #[foo = "bar"]
+}
+
+fn main() {
+}
diff --git a/tests/ui/parser/attribute/attr-dangling-in-fn.stderr b/tests/ui/parser/attribute/attr-dangling-in-fn.stderr
new file mode 100644
index 000000000..b1bb3ab3b
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr-dangling-in-mod.rs b/tests/ui/parser/attribute/attr-dangling-in-mod.rs
new file mode 100644
index 000000000..261ed3913
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-dangling-in-mod.rs
@@ -0,0 +1,6 @@
+// error-pattern:expected item
+
+fn main() {
+}
+
+#[foo = "bar"]
diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr
new file mode 100644
index 000000000..1c892eac0
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs
new file mode 100644
index 000000000..d1950087c
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs
@@ -0,0 +1,108 @@
+fn main() {}
+
+#[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 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/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr
new file mode 100644
index 000000000..e46c59108
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr
@@ -0,0 +1,446 @@
+error: expected expression, found `]`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:3: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:5: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:7: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: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:7: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
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: expected expression, found `)`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:7: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:11: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:11: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:14: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:16: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:18: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:20: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:22: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:24: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:26: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:28: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:30:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; }
+ | ^^ expected expression
+
+error: expected expression, found `..`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:32: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:34: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:36: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:38: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:40: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:42: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:44: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:46: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:48: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:50: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:52: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:54: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:56: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:58: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:60: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:62: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:64: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:66: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:68: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:71: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:73: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:75: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:77: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:79: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:85: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:85: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: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: unexpected token: `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:91: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:93: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:93: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:97: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:97: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: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: expected statement after outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:105:37
+ |
+LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
+ | ^^^^^^^
+
+error: expected statement after outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:107: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/tests/ui/parser/attribute/attr-with-a-semicolon.rs b/tests/ui/parser/attribute/attr-with-a-semicolon.rs
new file mode 100644
index 000000000..56fe40b91
--- /dev/null
+++ b/tests/ui/parser/attribute/attr-with-a-semicolon.rs
@@ -0,0 +1,4 @@
+#[derive(Debug, Clone)]; //~ERROR expected item after attributes
+struct Foo;
+
+fn main() {}
diff --git a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr
new file mode 100644
index 000000000..0de3490b8
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr.rs b/tests/ui/parser/attribute/attr.rs
new file mode 100644
index 000000000..42b2dfde8
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attr.stderr b/tests/ui/parser/attribute/attr.stderr
new file mode 100644
index 000000000..7cd0ac224
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs b/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs
new file mode 100644
index 000000000..c2cc91d8f
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr b/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr
new file mode 100644
index 000000000..4c5964715
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attrs-after-extern-mod.rs b/tests/ui/parser/attribute/attrs-after-extern-mod.rs
new file mode 100644
index 000000000..e3f0fa0fc
--- /dev/null
+++ b/tests/ui/parser/attribute/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/tests/ui/parser/attribute/attrs-after-extern-mod.stderr b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr
new file mode 100644
index 000000000..135d98457
--- /dev/null
+++ b/tests/ui/parser/attribute/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
+