summaryrefslogtreecommitdiffstats
path: root/tests/ui/attributes
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:58 +0000
commita4b7ed7a42c716ab9f05e351f003d589124fd55d (patch)
treeb620cd3f223850b28716e474e80c58059dca5dd4 /tests/ui/attributes
parentAdding upstream version 1.67.1+dfsg1. (diff)
downloadrustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.tar.xz
rustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.zip
Adding upstream version 1.68.2+dfsg1.upstream/1.68.2+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/attributes')
-rw-r--r--tests/ui/attributes/attr-before-view-item.rs10
-rw-r--r--tests/ui/attributes/attr-before-view-item2.rs12
-rw-r--r--tests/ui/attributes/attr-eq-token-tree.rs2
-rw-r--r--tests/ui/attributes/attr-eq-token-tree.stderr8
-rw-r--r--tests/ui/attributes/attr-mix-new.rs11
-rw-r--r--tests/ui/attributes/attrs-on-params.rs8
-rw-r--r--tests/ui/attributes/attrs-on-params.stderr17
-rw-r--r--tests/ui/attributes/attrs-with-no-formal-in-generics-1.rs13
-rw-r--r--tests/ui/attributes/attrs-with-no-formal-in-generics-1.stderr8
-rw-r--r--tests/ui/attributes/attrs-with-no-formal-in-generics-2.rs12
-rw-r--r--tests/ui/attributes/attrs-with-no-formal-in-generics-2.stderr8
-rw-r--r--tests/ui/attributes/attrs-with-no-formal-in-generics-3.rs12
-rw-r--r--tests/ui/attributes/attrs-with-no-formal-in-generics-3.stderr8
-rw-r--r--tests/ui/attributes/auxiliary/key-value-expansion.rs12
-rw-r--r--tests/ui/attributes/class-attributes-1.rs19
-rw-r--r--tests/ui/attributes/class-attributes-2.rs31
-rw-r--r--tests/ui/attributes/collapse-debuginfo-invalid.rs110
-rw-r--r--tests/ui/attributes/collapse-debuginfo-invalid.stderr222
-rw-r--r--tests/ui/attributes/const-stability-on-macro.rs16
-rw-r--r--tests/ui/attributes/const-stability-on-macro.stderr20
-rw-r--r--tests/ui/attributes/doc-attr.rs25
-rw-r--r--tests/ui/attributes/doc-attr.stderr71
-rw-r--r--tests/ui/attributes/duplicated-attributes.rs41
-rw-r--r--tests/ui/attributes/duplicated-attributes.stderr22
-rw-r--r--tests/ui/attributes/extented-attribute-macro-error.rs7
-rw-r--r--tests/ui/attributes/extented-attribute-macro-error.stderr10
-rw-r--r--tests/ui/attributes/field-attributes-vis-unresolved.rs25
-rw-r--r--tests/ui/attributes/field-attributes-vis-unresolved.stderr19
-rw-r--r--tests/ui/attributes/invalid-doc-attr.rs32
-rw-r--r--tests/ui/attributes/invalid-doc-attr.stderr78
-rw-r--r--tests/ui/attributes/issue-100631.rs8
-rw-r--r--tests/ui/attributes/issue-100631.stderr12
-rw-r--r--tests/ui/attributes/issue-105594-invalid-attr-validation.rs13
-rw-r--r--tests/ui/attributes/issue-105594-invalid-attr-validation.stderr26
-rw-r--r--tests/ui/attributes/issue-40962.rs11
-rw-r--r--tests/ui/attributes/issue-90873.rs9
-rw-r--r--tests/ui/attributes/issue-90873.stderr44
-rw-r--r--tests/ui/attributes/item-attributes.rs174
-rw-r--r--tests/ui/attributes/key-value-expansion-on-mac.rs14
-rw-r--r--tests/ui/attributes/key-value-expansion-on-mac.stderr8
-rw-r--r--tests/ui/attributes/key-value-expansion.rs55
-rw-r--r--tests/ui/attributes/key-value-expansion.stderr35
-rw-r--r--tests/ui/attributes/key-value-non-ascii.rs4
-rw-r--r--tests/ui/attributes/key-value-non-ascii.stderr13
-rw-r--r--tests/ui/attributes/log-backtrace.rs9
-rw-r--r--tests/ui/attributes/main-removed-1.rs2
-rw-r--r--tests/ui/attributes/main-removed-1.stderr10
-rw-r--r--tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs12
-rw-r--r--tests/ui/attributes/main-removed-2/main.rs11
-rw-r--r--tests/ui/attributes/method-attributes.rs28
-rw-r--r--tests/ui/attributes/multiple-invalid.rs10
-rw-r--r--tests/ui/attributes/multiple-invalid.stderr21
-rw-r--r--tests/ui/attributes/nonterminal-expansion.rs18
-rw-r--r--tests/ui/attributes/nonterminal-expansion.stderr25
-rw-r--r--tests/ui/attributes/obsolete-attr.rs9
-rw-r--r--tests/ui/attributes/obsolete-attr.stderr14
-rw-r--r--tests/ui/attributes/suffixed-literal-meta.rs15
-rw-r--r--tests/ui/attributes/suffixed-literal-meta.stderr98
-rw-r--r--tests/ui/attributes/tool_attributes.rs13
-rw-r--r--tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs33
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs4
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr13
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs5
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr14
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs13
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs14
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs4
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr15
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs6
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr8
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs8
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr8
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs9
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs13
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs15
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs13
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs6
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr8
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs6
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr8
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs4
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr8
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe.rs4
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe.stderr8
-rw-r--r--tests/ui/attributes/unknown-attr.rs12
-rw-r--r--tests/ui/attributes/unknown-attr.stderr20
-rw-r--r--tests/ui/attributes/unnamed-field-attributes-dup.rs11
-rw-r--r--tests/ui/attributes/unnamed-field-attributes-vis.rs11
-rw-r--r--tests/ui/attributes/unnamed-field-attributes.rs9
-rw-r--r--tests/ui/attributes/unrestricted-attribute-tokens.rs8
-rw-r--r--tests/ui/attributes/unused-item-in-attr.rs6
-rw-r--r--tests/ui/attributes/unused-item-in-attr.stderr16
-rw-r--r--tests/ui/attributes/used_with_arg.rs19
-rw-r--r--tests/ui/attributes/used_with_arg.stderr18
-rw-r--r--tests/ui/attributes/used_with_arg_no_mangle.rs9
-rw-r--r--tests/ui/attributes/used_with_multi_args.rs6
-rw-r--r--tests/ui/attributes/used_with_multi_args.stderr8
-rw-r--r--tests/ui/attributes/variant-attributes.rs37
-rw-r--r--tests/ui/attributes/z-crate-attr.rs12
99 files changed, 2059 insertions, 0 deletions
diff --git a/tests/ui/attributes/attr-before-view-item.rs b/tests/ui/attributes/attr-before-view-item.rs
new file mode 100644
index 000000000..e1588aada
--- /dev/null
+++ b/tests/ui/attributes/attr-before-view-item.rs
@@ -0,0 +1,10 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_attrs)]
+#![feature(test)]
+
+#[rustc_dummy = "bar"]
+extern crate test;
+
+fn main() {}
diff --git a/tests/ui/attributes/attr-before-view-item2.rs b/tests/ui/attributes/attr-before-view-item2.rs
new file mode 100644
index 000000000..c1f667372
--- /dev/null
+++ b/tests/ui/attributes/attr-before-view-item2.rs
@@ -0,0 +1,12 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_attrs)]
+#![feature(test)]
+
+mod m {
+ #[rustc_dummy = "bar"]
+ extern crate test;
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/attr-eq-token-tree.rs b/tests/ui/attributes/attr-eq-token-tree.rs
new file mode 100644
index 000000000..330b11977
--- /dev/null
+++ b/tests/ui/attributes/attr-eq-token-tree.rs
@@ -0,0 +1,2 @@
+#[my_attr = !] //~ ERROR expected expression, found `]`
+fn main() {}
diff --git a/tests/ui/attributes/attr-eq-token-tree.stderr b/tests/ui/attributes/attr-eq-token-tree.stderr
new file mode 100644
index 000000000..1846444b6
--- /dev/null
+++ b/tests/ui/attributes/attr-eq-token-tree.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `]`
+ --> $DIR/attr-eq-token-tree.rs:1:14
+ |
+LL | #[my_attr = !]
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/attr-mix-new.rs b/tests/ui/attributes/attr-mix-new.rs
new file mode 100644
index 000000000..8119df0c4
--- /dev/null
+++ b/tests/ui/attributes/attr-mix-new.rs
@@ -0,0 +1,11 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_attrs)]
+
+#[rustc_dummy(bar)]
+mod foo {
+ #![feature(globs)]
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/attrs-on-params.rs b/tests/ui/attributes/attrs-on-params.rs
new file mode 100644
index 000000000..158a4500b
--- /dev/null
+++ b/tests/ui/attributes/attrs-on-params.rs
@@ -0,0 +1,8 @@
+// This checks that incorrect params on function parameters are caught
+
+fn function(#[inline] param: u32) {
+ //~^ ERROR attribute should be applied to function or closure
+ //~| ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/attrs-on-params.stderr b/tests/ui/attributes/attrs-on-params.stderr
new file mode 100644
index 000000000..306e862cb
--- /dev/null
+++ b/tests/ui/attributes/attrs-on-params.stderr
@@ -0,0 +1,17 @@
+error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/attrs-on-params.rs:3:13
+ |
+LL | fn function(#[inline] param: u32) {
+ | ^^^^^^^^^
+
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/attrs-on-params.rs:3:13
+ |
+LL | fn function(#[inline] param: u32) {
+ | ^^^^^^^^^-----------
+ | |
+ | not a function or closure
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0518`.
diff --git a/tests/ui/attributes/attrs-with-no-formal-in-generics-1.rs b/tests/ui/attributes/attrs-with-no-formal-in-generics-1.rs
new file mode 100644
index 000000000..df9c8d894
--- /dev/null
+++ b/tests/ui/attributes/attrs-with-no-formal-in-generics-1.rs
@@ -0,0 +1,13 @@
+// This test checks variations on `<#[attr] 'a, #[oops]>`, where
+// `#[oops]` is left dangling (that is, it is unattached, with no
+// formal binding following it).
+
+#![feature(rustc_attrs)]
+
+struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
+
+impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
+ //~^ ERROR trailing attribute after generic parameter
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/attrs-with-no-formal-in-generics-1.stderr b/tests/ui/attributes/attrs-with-no-formal-in-generics-1.stderr
new file mode 100644
index 000000000..5b4f5222a
--- /dev/null
+++ b/tests/ui/attributes/attrs-with-no-formal-in-generics-1.stderr
@@ -0,0 +1,8 @@
+error: trailing attribute after generic parameter
+ --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:29
+ |
+LL | impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
+ | ^^^^^^^ attributes must go before parameters
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/attrs-with-no-formal-in-generics-2.rs b/tests/ui/attributes/attrs-with-no-formal-in-generics-2.rs
new file mode 100644
index 000000000..d1d044035
--- /dev/null
+++ b/tests/ui/attributes/attrs-with-no-formal-in-generics-2.rs
@@ -0,0 +1,12 @@
+// This test checks variations on `<#[attr] 'a, #[oops]>`, where
+// `#[oops]` is left dangling (that is, it is unattached, with no
+// formal binding following it).
+
+#![feature(rustc_attrs)]
+
+struct RefAny<'a, T>(&'a T);
+
+impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {}
+//~^ ERROR trailing attribute after generic parameter
+
+fn main() {}
diff --git a/tests/ui/attributes/attrs-with-no-formal-in-generics-2.stderr b/tests/ui/attributes/attrs-with-no-formal-in-generics-2.stderr
new file mode 100644
index 000000000..fce3ff7de
--- /dev/null
+++ b/tests/ui/attributes/attrs-with-no-formal-in-generics-2.stderr
@@ -0,0 +1,8 @@
+error: trailing attribute after generic parameter
+ --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:43
+ |
+LL | impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {}
+ | ^^^^^^^ attributes must go before parameters
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/attrs-with-no-formal-in-generics-3.rs b/tests/ui/attributes/attrs-with-no-formal-in-generics-3.rs
new file mode 100644
index 000000000..3cfc70b41
--- /dev/null
+++ b/tests/ui/attributes/attrs-with-no-formal-in-generics-3.rs
@@ -0,0 +1,12 @@
+// This test checks variations on `<#[attr] 'a, #[oops]>`, where
+// `#[oops]` is left dangling (that is, it is unattached, with no
+// formal binding following it).
+
+struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
+
+fn hof_lt<Q>(_: Q)
+ where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32
+ //~^ ERROR trailing attribute after generic parameter
+{}
+
+fn main() {}
diff --git a/tests/ui/attributes/attrs-with-no-formal-in-generics-3.stderr b/tests/ui/attributes/attrs-with-no-formal-in-generics-3.stderr
new file mode 100644
index 000000000..b9ca00974
--- /dev/null
+++ b/tests/ui/attributes/attrs-with-no-formal-in-generics-3.stderr
@@ -0,0 +1,8 @@
+error: trailing attribute after generic parameter
+ --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:44
+ |
+LL | where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32
+ | ^^^^^^^ attributes must go before parameters
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/auxiliary/key-value-expansion.rs b/tests/ui/attributes/auxiliary/key-value-expansion.rs
new file mode 100644
index 000000000..b4eb80bb5
--- /dev/null
+++ b/tests/ui/attributes/auxiliary/key-value-expansion.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_derive(EthabiContract, attributes(ethabi_contract_options))]
+pub fn ethabi_derive(input: TokenStream) -> TokenStream {
+ Default::default()
+}
diff --git a/tests/ui/attributes/class-attributes-1.rs b/tests/ui/attributes/class-attributes-1.rs
new file mode 100644
index 000000000..027b701e5
--- /dev/null
+++ b/tests/ui/attributes/class-attributes-1.rs
@@ -0,0 +1,19 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// pp-exact - Make sure we actually print the attributes
+
+#![feature(rustc_attrs)]
+
+struct Cat {
+ name: String,
+}
+
+impl Drop for Cat {
+ #[rustc_dummy]
+ fn drop(&mut self) { println!("{} landed on hir feet" , self . name); }
+}
+
+
+#[rustc_dummy]
+fn cat(name: String) -> Cat { Cat{name: name,} }
+
+fn main() { let _kitty = cat("Spotty".to_string()); }
diff --git a/tests/ui/attributes/class-attributes-2.rs b/tests/ui/attributes/class-attributes-2.rs
new file mode 100644
index 000000000..6aba6b894
--- /dev/null
+++ b/tests/ui/attributes/class-attributes-2.rs
@@ -0,0 +1,31 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![feature(rustc_attrs)]
+
+struct Cat {
+ name: String,
+}
+
+impl Drop for Cat {
+ #[rustc_dummy]
+ /**
+ Actually, cats don't always land on their feet when you drop them.
+ */
+ fn drop(&mut self) {
+ println!("{} landed on hir feet", self.name);
+ }
+}
+
+#[rustc_dummy]
+/**
+Maybe it should technically be a kitten_maker.
+*/
+fn cat(name: String) -> Cat {
+ Cat {
+ name: name
+ }
+}
+
+fn main() {
+ let _kitty = cat("Spotty".to_string());
+}
diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs
new file mode 100644
index 000000000..42d8982c1
--- /dev/null
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs
@@ -0,0 +1,110 @@
+#![feature(collapse_debuginfo)]
+#![feature(stmt_expr_attributes)]
+#![feature(type_alias_impl_trait)]
+#![no_std]
+
+// Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions.
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+extern crate std;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+use std::collections::HashMap;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+static FOO: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+const BAR: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+fn foo() {
+ let _ = #[collapse_debuginfo] || { };
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ let _ = 3;
+ let _ = #[collapse_debuginfo] 3;
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ match (3, 4) {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ _ => (),
+ }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+mod bar {
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type Map = HashMap<u32, u32>;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+enum Foo {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ Variant,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+struct Bar {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ field: u32,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+union Qux {
+ a: u32,
+ b: u16
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+trait Foobar {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ type Bar;
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type AFoobar = impl Foobar;
+
+impl Foobar for Bar {
+ type Bar = u32;
+}
+
+fn constraining() -> AFoobar {
+ Bar { field: 3 }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+impl Bar {
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ const FOO: u32 = 3;
+
+ #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+ fn bar(&self) {}
+}
+
+#[collapse_debuginfo]
+macro_rules! finally {
+ ($e:expr) => { $e }
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
new file mode 100644
index 000000000..01c476091
--- /dev/null
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -0,0 +1,222 @@
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:8:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | extern crate std;
+ | ----------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:12:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | use std::collections::HashMap;
+ | ------------------------------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:16:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | static FOO: u32 = 3;
+ | -------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:20:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const BAR: u32 = 3;
+ | ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:24:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / fn foo() {
+LL | | let _ = #[collapse_debuginfo] || { };
+LL | |
+LL | | #[collapse_debuginfo]
+... |
+LL | | }
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:27:13
+ |
+LL | let _ = #[collapse_debuginfo] || { };
+ | ^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:29:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | let _ = 3;
+ | ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:32:13
+ |
+LL | let _ = #[collapse_debuginfo] 3;
+ | ^^^^^^^^^^^^^^^^^^^^^ - not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:35:9
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | _ => (),
+ | ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:41:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / mod bar {
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:46:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type Map = HashMap<u32, u32>;
+ | ----------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:50:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / enum Foo {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | Variant,
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:53:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | Variant,
+ | ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:58:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / struct Bar {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | field: u32,
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:61:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | field: u32,
+ | ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:66:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / union Qux {
+LL | | a: u32,
+LL | | b: u16
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:73:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / trait Foobar {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | type Bar;
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:81:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type AFoobar = impl Foobar;
+ | --------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:93:1
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / impl Bar {
+LL | | #[collapse_debuginfo]
+LL | |
+LL | | const FOO: u32 = 3;
+... |
+LL | | fn bar(&self) {}
+LL | | }
+ | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:76:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type Bar;
+ | --------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:96:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const FOO: u32 = 3;
+ | ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+ --> $DIR/collapse-debuginfo-invalid.rs:100:5
+ |
+LL | #[collapse_debuginfo]
+ | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | fn bar(&self) {}
+ | ---------------- not a macro definition
+
+error: aborting due to 22 previous errors
+
diff --git a/tests/ui/attributes/const-stability-on-macro.rs b/tests/ui/attributes/const-stability-on-macro.rs
new file mode 100644
index 000000000..412af195d
--- /dev/null
+++ b/tests/ui/attributes/const-stability-on-macro.rs
@@ -0,0 +1,16 @@
+#![feature(staged_api)]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[rustc_const_stable(feature = "foo", since = "0")]
+//~^ ERROR macros cannot have const stability attributes
+macro_rules! foo {
+ () => {};
+}
+
+#[rustc_const_unstable(feature = "bar", issue="none")]
+//~^ ERROR macros cannot have const stability attributes
+macro_rules! bar {
+ () => {};
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/const-stability-on-macro.stderr b/tests/ui/attributes/const-stability-on-macro.stderr
new file mode 100644
index 000000000..c3da02c79
--- /dev/null
+++ b/tests/ui/attributes/const-stability-on-macro.stderr
@@ -0,0 +1,20 @@
+error: macros cannot have const stability attributes
+ --> $DIR/const-stability-on-macro.rs:4:1
+ |
+LL | #[rustc_const_stable(feature = "foo", since = "0")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
+LL |
+LL | macro_rules! foo {
+ | ---------------- const stability attribute affects this macro
+
+error: macros cannot have const stability attributes
+ --> $DIR/const-stability-on-macro.rs:10:1
+ |
+LL | #[rustc_const_unstable(feature = "bar", issue="none")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
+LL |
+LL | macro_rules! bar {
+ | ---------------- const stability attribute affects this macro
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/attributes/doc-attr.rs b/tests/ui/attributes/doc-attr.rs
new file mode 100644
index 000000000..980d1c0e2
--- /dev/null
+++ b/tests/ui/attributes/doc-attr.rs
@@ -0,0 +1,25 @@
+#![crate_type = "lib"]
+#![deny(warnings)]
+#![doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~^^ WARN
+
+#[doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~^^ WARN
+pub fn foo() {}
+
+#[doc(123)]
+//~^ ERROR invalid `doc` attribute
+//~| WARN
+#[doc("hello", "bar")]
+//~^ ERROR invalid `doc` attribute
+//~| WARN
+//~| ERROR invalid `doc` attribute
+//~| WARN
+#[doc(foo::bar, crate::bar::baz = "bye")]
+//~^ ERROR unknown `doc` attribute
+//~| WARN
+//~| ERROR unknown `doc` attribute
+//~| WARN
+fn bar() {}
diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr
new file mode 100644
index 000000000..68df2771f
--- /dev/null
+++ b/tests/ui/attributes/doc-attr.stderr
@@ -0,0 +1,71 @@
+error: unknown `doc` attribute `as_ptr`
+ --> $DIR/doc-attr.rs:7:7
+ |
+LL | #[doc(as_ptr)]
+ | ^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+note: the lint level is defined here
+ --> $DIR/doc-attr.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+
+error: invalid `doc` attribute
+ --> $DIR/doc-attr.rs:12:7
+ |
+LL | #[doc(123)]
+ | ^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: invalid `doc` attribute
+ --> $DIR/doc-attr.rs:15:7
+ |
+LL | #[doc("hello", "bar")]
+ | ^^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: invalid `doc` attribute
+ --> $DIR/doc-attr.rs:15:16
+ |
+LL | #[doc("hello", "bar")]
+ | ^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: unknown `doc` attribute `foo::bar`
+ --> $DIR/doc-attr.rs:20:7
+ |
+LL | #[doc(foo::bar, crate::bar::baz = "bye")]
+ | ^^^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: unknown `doc` attribute `crate::bar::baz`
+ --> $DIR/doc-attr.rs:20:17
+ |
+LL | #[doc(foo::bar, crate::bar::baz = "bye")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: unknown `doc` attribute `as_ptr`
+ --> $DIR/doc-attr.rs:3:8
+ |
+LL | #![doc(as_ptr)]
+ | ^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/attributes/duplicated-attributes.rs b/tests/ui/attributes/duplicated-attributes.rs
new file mode 100644
index 000000000..84a5abcf8
--- /dev/null
+++ b/tests/ui/attributes/duplicated-attributes.rs
@@ -0,0 +1,41 @@
+// Test that, if an item is annotated with a builtin attribute more than once, a warning is
+// emitted.
+// Tests https://github.com/rust-lang/rust/issues/90979
+
+// check-pass
+// compile-flags: --test
+
+#![feature(test)]
+#![feature(cfg_eval)]
+
+#[test]
+#[test]
+//~^ WARNING duplicated attribute
+fn f() {}
+
+// The following shouldn't trigger an error. The attribute is not duplicated.
+#[test]
+fn f2() {}
+
+// The following shouldn't trigger an error either. The second attribute is not #[test].
+#[test]
+#[inline]
+fn f3() {}
+
+extern crate test;
+use test::Bencher;
+
+#[bench]
+#[bench]
+//~^ WARNING duplicated attribute
+fn f4(_: &mut Bencher) {}
+
+#[cfg_eval]
+#[cfg_eval]
+//~^ WARNING duplicated attribute
+struct S;
+
+#[cfg_eval]
+struct S2;
+
+fn main() {}
diff --git a/tests/ui/attributes/duplicated-attributes.stderr b/tests/ui/attributes/duplicated-attributes.stderr
new file mode 100644
index 000000000..735d950b2
--- /dev/null
+++ b/tests/ui/attributes/duplicated-attributes.stderr
@@ -0,0 +1,22 @@
+warning: duplicated attribute
+ --> $DIR/duplicated-attributes.rs:12:1
+ |
+LL | #[test]
+ | ^^^^^^^
+ |
+ = note: `#[warn(duplicate_macro_attributes)]` on by default
+
+warning: duplicated attribute
+ --> $DIR/duplicated-attributes.rs:29:1
+ |
+LL | #[bench]
+ | ^^^^^^^^
+
+warning: duplicated attribute
+ --> $DIR/duplicated-attributes.rs:34:1
+ |
+LL | #[cfg_eval]
+ | ^^^^^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/attributes/extented-attribute-macro-error.rs b/tests/ui/attributes/extented-attribute-macro-error.rs
new file mode 100644
index 000000000..492f84f56
--- /dev/null
+++ b/tests/ui/attributes/extented-attribute-macro-error.rs
@@ -0,0 +1,7 @@
+// normalize-stderr-test: "couldn't read.*" -> "couldn't read the file"
+
+#![doc = include_str!("../not_existing_file.md")]
+struct Documented {}
+//~^^ ERROR couldn't read
+
+fn main() {}
diff --git a/tests/ui/attributes/extented-attribute-macro-error.stderr b/tests/ui/attributes/extented-attribute-macro-error.stderr
new file mode 100644
index 000000000..0fcde9b7c
--- /dev/null
+++ b/tests/ui/attributes/extented-attribute-macro-error.stderr
@@ -0,0 +1,10 @@
+error: couldn't read the file
+ --> $DIR/extented-attribute-macro-error.rs:3:10
+ |
+LL | #![doc = include_str!("../not_existing_file.md")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.rs b/tests/ui/attributes/field-attributes-vis-unresolved.rs
new file mode 100644
index 000000000..d1bd2a1e7
--- /dev/null
+++ b/tests/ui/attributes/field-attributes-vis-unresolved.rs
@@ -0,0 +1,25 @@
+// Non-builtin attributes do not mess with field visibility resolution (issue #67006).
+
+mod internal {
+ struct S {
+ #[rustfmt::skip]
+ pub(in crate::internal) field: u8 // OK
+ }
+
+ struct Z(
+ #[rustfmt::skip]
+ pub(in crate::internal) u8 // OK
+ );
+}
+
+struct S {
+ #[rustfmt::skip]
+ pub(in nonexistent) field: u8 //~ ERROR failed to resolve
+}
+
+struct Z(
+ #[rustfmt::skip]
+ pub(in nonexistent) u8 //~ ERROR failed to resolve
+);
+
+fn main() {}
diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.stderr b/tests/ui/attributes/field-attributes-vis-unresolved.stderr
new file mode 100644
index 000000000..439762546
--- /dev/null
+++ b/tests/ui/attributes/field-attributes-vis-unresolved.stderr
@@ -0,0 +1,19 @@
+error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
+ --> $DIR/field-attributes-vis-unresolved.rs:17:12
+ |
+LL | pub(in nonexistent) field: u8
+ | ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+ |
+ = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
+
+error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
+ --> $DIR/field-attributes-vis-unresolved.rs:22:12
+ |
+LL | pub(in nonexistent) u8
+ | ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+ |
+ = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/attributes/invalid-doc-attr.rs b/tests/ui/attributes/invalid-doc-attr.rs
new file mode 100644
index 000000000..de004b41e
--- /dev/null
+++ b/tests/ui/attributes/invalid-doc-attr.rs
@@ -0,0 +1,32 @@
+#![crate_type = "lib"]
+#![deny(warnings)]
+
+#[doc(test(no_crate_inject))]
+//~^ ERROR can only be applied at the crate level
+//~| WARN is being phased out
+//~| HELP to apply to the crate, use an inner attribute
+//~| SUGGESTION #![doc(test(no_crate_inject))]
+#[doc(inline)]
+//~^ ERROR can only be applied to a `use` item
+//~| WARN is being phased out
+pub fn foo() {}
+
+pub mod bar {
+ #![doc(test(no_crate_inject))]
+ //~^ ERROR can only be applied at the crate level
+ //~| WARN is being phased out
+
+ #[doc(test(no_crate_inject))]
+ //~^ ERROR can only be applied at the crate level
+ //~| WARN is being phased out
+ #[doc(inline)]
+ //~^ ERROR can only be applied to a `use` item
+ //~| WARN is being phased out
+ pub fn baz() {}
+}
+
+#[doc(inline)]
+#[doc(no_inline)]
+//~^^ ERROR conflicting doc inlining attributes
+//~| HELP remove one of the conflicting attributes
+pub use bar::baz;
diff --git a/tests/ui/attributes/invalid-doc-attr.stderr b/tests/ui/attributes/invalid-doc-attr.stderr
new file mode 100644
index 000000000..3c66e587b
--- /dev/null
+++ b/tests/ui/attributes/invalid-doc-attr.stderr
@@ -0,0 +1,78 @@
+error: this attribute can only be applied at the crate level
+ --> $DIR/invalid-doc-attr.rs:4:7
+ |
+LL | #[doc(test(no_crate_inject))]
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+ = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
+note: the lint level is defined here
+ --> $DIR/invalid-doc-attr.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+help: to apply to the crate, use an inner attribute
+ |
+LL | #![doc(test(no_crate_inject))]
+ |
+
+error: this attribute can only be applied to a `use` item
+ --> $DIR/invalid-doc-attr.rs:9:7
+ |
+LL | #[doc(inline)]
+ | ^^^^^^ only applicable on `use` items
+...
+LL | pub fn foo() {}
+ | ------------ not a `use` item
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+ = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
+
+error: this attribute can only be applied at the crate level
+ --> $DIR/invalid-doc-attr.rs:15:12
+ |
+LL | #![doc(test(no_crate_inject))]
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+ = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
+
+error: conflicting doc inlining attributes
+ --> $DIR/invalid-doc-attr.rs:28:7
+ |
+LL | #[doc(inline)]
+ | ^^^^^^ this attribute...
+LL | #[doc(no_inline)]
+ | ^^^^^^^^^ ...conflicts with this attribute
+ |
+ = help: remove one of the conflicting attributes
+
+error: this attribute can only be applied at the crate level
+ --> $DIR/invalid-doc-attr.rs:19:11
+ |
+LL | #[doc(test(no_crate_inject))]
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+ = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
+
+error: this attribute can only be applied to a `use` item
+ --> $DIR/invalid-doc-attr.rs:22:11
+ |
+LL | #[doc(inline)]
+ | ^^^^^^ only applicable on `use` items
+...
+LL | pub fn baz() {}
+ | ------------ not a `use` item
+ |
+ = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+ = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/attributes/issue-100631.rs b/tests/ui/attributes/issue-100631.rs
new file mode 100644
index 000000000..0fefcf83f
--- /dev/null
+++ b/tests/ui/attributes/issue-100631.rs
@@ -0,0 +1,8 @@
+// issue #100631, make sure `TyCtxt::get_attr` only called by case that compiler
+// can reasonably deal with multiple attributes.
+// `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`.
+#[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084]
+#[repr(C)]
+enum Foo {}
+
+fn main() {}
diff --git a/tests/ui/attributes/issue-100631.stderr b/tests/ui/attributes/issue-100631.stderr
new file mode 100644
index 000000000..caa5351dd
--- /dev/null
+++ b/tests/ui/attributes/issue-100631.stderr
@@ -0,0 +1,12 @@
+error[E0084]: unsupported representation for zero-variant enum
+ --> $DIR/issue-100631.rs:4:1
+ |
+LL | #[repr(C)]
+ | ^^^^^^^^^^
+LL | #[repr(C)]
+LL | enum Foo {}
+ | -------- zero-variant enum
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0084`.
diff --git a/tests/ui/attributes/issue-105594-invalid-attr-validation.rs b/tests/ui/attributes/issue-105594-invalid-attr-validation.rs
new file mode 100644
index 000000000..6c68e6b04
--- /dev/null
+++ b/tests/ui/attributes/issue-105594-invalid-attr-validation.rs
@@ -0,0 +1,13 @@
+// This checks that the attribute validation ICE in issue #105594 doesn't
+// recur.
+//
+// ignore-thumbv8m.base
+#![feature(cmse_nonsecure_entry)]
+
+fn main() {}
+
+#[track_caller] //~ ERROR attribute should be applied to a function
+static _A: () = ();
+
+#[cmse_nonsecure_entry] //~ ERROR attribute should be applied to a function
+static _B: () = (); //~| ERROR #[cmse_nonsecure_entry]` is only valid for targets
diff --git a/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr b/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr
new file mode 100644
index 000000000..c6b2d6e78
--- /dev/null
+++ b/tests/ui/attributes/issue-105594-invalid-attr-validation.stderr
@@ -0,0 +1,26 @@
+error[E0739]: attribute should be applied to a function definition
+ --> $DIR/issue-105594-invalid-attr-validation.rs:9:1
+ |
+LL | #[track_caller]
+ | ^^^^^^^^^^^^^^^
+LL | static _A: () = ();
+ | ------------------- not a function definition
+
+error: attribute should be applied to a function definition
+ --> $DIR/issue-105594-invalid-attr-validation.rs:12:1
+ |
+LL | #[cmse_nonsecure_entry]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+LL | static _B: () = ();
+ | ------------------- not a function definition
+
+error[E0775]: `#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension
+ --> $DIR/issue-105594-invalid-attr-validation.rs:12:1
+ |
+LL | #[cmse_nonsecure_entry]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0739, E0775.
+For more information about an error, try `rustc --explain E0739`.
diff --git a/tests/ui/attributes/issue-40962.rs b/tests/ui/attributes/issue-40962.rs
new file mode 100644
index 000000000..7b91c0681
--- /dev/null
+++ b/tests/ui/attributes/issue-40962.rs
@@ -0,0 +1,11 @@
+// check-pass
+macro_rules! m {
+ ($i:meta) => {
+ #[derive($i)]
+ struct S;
+ }
+}
+
+m!(Clone);
+
+fn main() {}
diff --git a/tests/ui/attributes/issue-90873.rs b/tests/ui/attributes/issue-90873.rs
new file mode 100644
index 000000000..1411f6174
--- /dev/null
+++ b/tests/ui/attributes/issue-90873.rs
@@ -0,0 +1,9 @@
+#![u=||{static d=||1;}]
+//~^ unexpected expression
+//~| cannot find attribute `u` in this scope
+//~| missing type for `static` item
+
+#![a={impl std::ops::Neg for i8 {}}]
+//~^ ERROR unexpected expression
+//~| ERROR cannot find attribute `a` in this scope
+//~| ERROR `main` function not found in crate `issue_90873`
diff --git a/tests/ui/attributes/issue-90873.stderr b/tests/ui/attributes/issue-90873.stderr
new file mode 100644
index 000000000..894ec8341
--- /dev/null
+++ b/tests/ui/attributes/issue-90873.stderr
@@ -0,0 +1,44 @@
+error: unexpected expression: `||
+ {
+ static d: _ = || 1;
+ }`
+ --> $DIR/issue-90873.rs:1:6
+ |
+LL | #![u=||{static d=||1;}]
+ | ^^^^^^^^^^^^^^^^^
+
+error: unexpected expression: `{
+ impl std::ops::Neg for i8 {}
+ }`
+ --> $DIR/issue-90873.rs:6:6
+ |
+LL | #![a={impl std::ops::Neg for i8 {}}]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `u` in this scope
+ --> $DIR/issue-90873.rs:1:4
+ |
+LL | #![u=||{static d=||1;}]
+ | ^
+
+error: cannot find attribute `a` in this scope
+ --> $DIR/issue-90873.rs:6:4
+ |
+LL | #![a={impl std::ops::Neg for i8 {}}]
+ | ^
+
+error[E0601]: `main` function not found in crate `issue_90873`
+ --> $DIR/issue-90873.rs:6:37
+ |
+LL | #![a={impl std::ops::Neg for i8 {}}]
+ | ^ consider adding a `main` function to `$DIR/issue-90873.rs`
+
+error: missing type for `static` item
+ --> $DIR/issue-90873.rs:1:17
+ |
+LL | #![u=||{static d=||1;}]
+ | ^ help: provide a type for the item: `: <type>`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/tests/ui/attributes/item-attributes.rs b/tests/ui/attributes/item-attributes.rs
new file mode 100644
index 000000000..c6bf6c656
--- /dev/null
+++ b/tests/ui/attributes/item-attributes.rs
@@ -0,0 +1,174 @@
+// These are attributes of the implicit crate. Really this just needs to parse
+// for completeness since .rs files linked from .rc files support this
+// notation to specify their module's attributes
+
+// check-pass
+
+#![feature(rustc_attrs)]
+#![rustc_dummy = "val"]
+#![rustc_dummy = "val"]
+#![rustc_dummy]
+#![rustc_dummy(attr5)]
+
+// These are attributes of the following mod
+#[rustc_dummy = "val"]
+#[rustc_dummy = "val"]
+mod test_first_item_in_file_mod {}
+
+mod test_single_attr_outer {
+ #[rustc_dummy = "val"]
+ pub static X: isize = 10;
+
+ #[rustc_dummy = "val"]
+ pub fn f() {}
+
+ #[rustc_dummy = "val"]
+ pub mod mod1 {}
+
+ pub mod rustrt {
+ #[rustc_dummy = "val"]
+ extern "C" {}
+ }
+}
+
+mod test_multi_attr_outer {
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ pub static X: isize = 10;
+
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ pub fn f() {}
+
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ pub mod mod1 {}
+
+ pub mod rustrt {
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ extern "C" {}
+ }
+
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ struct T {
+ x: isize,
+ }
+}
+
+mod test_stmt_single_attr_outer {
+ pub fn f() {
+ #[rustc_dummy = "val"]
+ static X: isize = 10;
+
+ #[rustc_dummy = "val"]
+ fn f() {}
+
+ #[rustc_dummy = "val"]
+ mod mod1 {}
+
+ mod rustrt {
+ #[rustc_dummy = "val"]
+ extern "C" {}
+ }
+ }
+}
+
+mod test_stmt_multi_attr_outer {
+ pub fn f() {
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ static X: isize = 10;
+
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ fn f() {}
+
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ mod mod1 {}
+
+ mod rustrt {
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ extern "C" {}
+ }
+ }
+}
+
+mod test_attr_inner {
+ pub mod m {
+ // This is an attribute of mod m
+ #![rustc_dummy = "val"]
+ }
+}
+
+mod test_attr_inner_then_outer {
+ pub mod m {
+ // This is an attribute of mod m
+ #![rustc_dummy = "val"]
+ // This is an attribute of fn f
+ #[rustc_dummy = "val"]
+ fn f() {}
+ }
+}
+
+mod test_attr_inner_then_outer_multi {
+ pub mod m {
+ // This is an attribute of mod m
+ #![rustc_dummy = "val"]
+ #![rustc_dummy = "val"]
+ // This is an attribute of fn f
+ #[rustc_dummy = "val"]
+ #[rustc_dummy = "val"]
+ fn f() {}
+ }
+}
+
+mod test_distinguish_syntax_ext {
+ pub fn f() {
+ format!("test{}", "s");
+ #[rustc_dummy = "val"]
+ fn g() {}
+ }
+}
+
+mod test_other_forms {
+ #[rustc_dummy]
+ #[rustc_dummy(word)]
+ #[rustc_dummy(attr(word))]
+ #[rustc_dummy(key1 = "val", key2 = "val", attr)]
+ pub fn f() {}
+}
+
+mod test_foreign_items {
+ pub mod rustrt {
+ extern "C" {
+ #![rustc_dummy]
+
+ #[rustc_dummy]
+ fn rust_get_test_int() -> u32;
+ }
+ }
+}
+
+// FIXME(#623): - these aren't supported yet
+/*mod test_literals {
+ #![str = "s"]
+ #![char = 'c']
+ #![isize = 100]
+ #![usize = 100_usize]
+ #![mach_int = 100u32]
+ #![float = 1.0]
+ #![mach_float = 1.0f32]
+ #![nil = ()]
+ #![bool = true]
+ mod m {}
+}*/
+
+fn test_fn_inner() {
+ #![rustc_dummy]
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/key-value-expansion-on-mac.rs b/tests/ui/attributes/key-value-expansion-on-mac.rs
new file mode 100644
index 000000000..c1d68d8cd
--- /dev/null
+++ b/tests/ui/attributes/key-value-expansion-on-mac.rs
@@ -0,0 +1,14 @@
+#![feature(rustc_attrs)]
+
+#[rustc_dummy = stringify!(a)] // OK
+macro_rules! bar {
+ () => {};
+}
+
+// FIXME?: `bar` here expands before `stringify` has a chance to expand.
+// `#[rustc_dummy = ...]` is validated and dropped during expansion of `bar`,
+// the "unexpected expression" errors comes from the validation.
+#[rustc_dummy = stringify!(b)] //~ ERROR unexpected expression: `stringify!(b)`
+bar!();
+
+fn main() {}
diff --git a/tests/ui/attributes/key-value-expansion-on-mac.stderr b/tests/ui/attributes/key-value-expansion-on-mac.stderr
new file mode 100644
index 000000000..64ab892d9
--- /dev/null
+++ b/tests/ui/attributes/key-value-expansion-on-mac.stderr
@@ -0,0 +1,8 @@
+error: unexpected expression: `stringify!(b)`
+ --> $DIR/key-value-expansion-on-mac.rs:11:17
+ |
+LL | #[rustc_dummy = stringify!(b)]
+ | ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/key-value-expansion.rs b/tests/ui/attributes/key-value-expansion.rs
new file mode 100644
index 000000000..83d601e5e
--- /dev/null
+++ b/tests/ui/attributes/key-value-expansion.rs
@@ -0,0 +1,55 @@
+// Regression tests for issue #55414, expansion happens in the value of a key-value attribute,
+// and the expanded expression is more complex than simply a macro call.
+
+// aux-build:key-value-expansion.rs
+
+#![feature(rustc_attrs)]
+
+extern crate key_value_expansion;
+
+// Minimized test case.
+
+macro_rules! bug {
+ ($expr:expr) => {
+ #[rustc_dummy = $expr] // Any key-value attribute, not necessarily `doc`
+ struct S;
+ };
+}
+
+// Any expressions containing macro call `X` that's more complex than `X` itself.
+// Parentheses will work.
+bug!((column!())); //~ ERROR unexpected expression: `(7u32)`
+
+// Original test case.
+
+macro_rules! bug {
+ () => {
+ bug!("bug" + stringify!(found)); //~ ERROR unexpected expression: `"bug" + "found"`
+ };
+ ($test:expr) => {
+ #[doc = $test]
+ struct Test {}
+ };
+}
+
+bug!();
+
+// Test case from #66804.
+
+macro_rules! doc_comment {
+ ($x:expr) => {
+ #[doc = $x]
+ extern {}
+ };
+}
+
+macro_rules! some_macro {
+ ($t1: ty) => {
+ doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
+ //~^ ERROR unexpected expression: `{
+ };
+}
+
+some_macro!(u8);
+
+fn main() {}
diff --git a/tests/ui/attributes/key-value-expansion.stderr b/tests/ui/attributes/key-value-expansion.stderr
new file mode 100644
index 000000000..1b776322a
--- /dev/null
+++ b/tests/ui/attributes/key-value-expansion.stderr
@@ -0,0 +1,35 @@
+error: unexpected expression: `(7u32)`
+ --> $DIR/key-value-expansion.rs:21:6
+ |
+LL | bug!((column!()));
+ | ^^^^^^^^^^^
+
+error: unexpected expression: `"bug" + "found"`
+ --> $DIR/key-value-expansion.rs:27:14
+ |
+LL | bug!("bug" + stringify!(found));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | bug!();
+ | ------ in this macro invocation
+ |
+ = note: this error originates in the macro `bug` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: unexpected expression: `{
+ let res =
+ ::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""],
+ &[::core::fmt::ArgumentV1::new_display(&"u8")]));
+ res
+ }.as_str()`
+ --> $DIR/key-value-expansion.rs:48:23
+ |
+LL | doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | some_macro!(u8);
+ | --------------- in this macro invocation
+ |
+ = note: this error originates in the macro `some_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/attributes/key-value-non-ascii.rs b/tests/ui/attributes/key-value-non-ascii.rs
new file mode 100644
index 000000000..e14e2fc05
--- /dev/null
+++ b/tests/ui/attributes/key-value-non-ascii.rs
@@ -0,0 +1,4 @@
+#![feature(rustc_attrs)]
+
+#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte string literal
+fn main() {}
diff --git a/tests/ui/attributes/key-value-non-ascii.stderr b/tests/ui/attributes/key-value-non-ascii.stderr
new file mode 100644
index 000000000..23d482de6
--- /dev/null
+++ b/tests/ui/attributes/key-value-non-ascii.stderr
@@ -0,0 +1,13 @@
+error: non-ASCII character in byte string literal
+ --> $DIR/key-value-non-ascii.rs:3:19
+ |
+LL | #[rustc_dummy = b"ffi.rs"]
+ | ^ must be ASCII
+ |
+help: if you meant to use the UTF-8 encoding of 'ffi', use \xHH escapes
+ |
+LL | #[rustc_dummy = b"/xEF/xAC/x83.rs"]
+ | ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/log-backtrace.rs b/tests/ui/attributes/log-backtrace.rs
new file mode 100644
index 000000000..3979d2001
--- /dev/null
+++ b/tests/ui/attributes/log-backtrace.rs
@@ -0,0 +1,9 @@
+// run-pass
+//
+// This test makes sure that log-backtrace option doesn't give a compilation error.
+//
+// dont-check-compiler-stdout
+// dont-check-compiler-stderr
+// rustc-env:RUSTC_LOG=info
+// compile-flags: -Zlog-backtrace=rustc_metadata::creader
+fn main() {}
diff --git a/tests/ui/attributes/main-removed-1.rs b/tests/ui/attributes/main-removed-1.rs
new file mode 100644
index 000000000..0e887469d
--- /dev/null
+++ b/tests/ui/attributes/main-removed-1.rs
@@ -0,0 +1,2 @@
+#[main] //~ ERROR cannot find attribute `main` in this scope
+fn main() {}
diff --git a/tests/ui/attributes/main-removed-1.stderr b/tests/ui/attributes/main-removed-1.stderr
new file mode 100644
index 000000000..2422c5c3b
--- /dev/null
+++ b/tests/ui/attributes/main-removed-1.stderr
@@ -0,0 +1,10 @@
+error: cannot find attribute `main` in this scope
+ --> $DIR/main-removed-1.rs:1:3
+ |
+LL | #[main]
+ | ^^^^
+ |
+ = note: `main` is in scope, but it is a function, not an attribute
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs b/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs
new file mode 100644
index 000000000..196b5be2d
--- /dev/null
+++ b/tests/ui/attributes/main-removed-2/auxiliary/tokyo.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn main(_: TokenStream, input: TokenStream) -> TokenStream {
+ "fn main() { println!(\"Hello Tokyo!\"); }".parse().unwrap()
+}
diff --git a/tests/ui/attributes/main-removed-2/main.rs b/tests/ui/attributes/main-removed-2/main.rs
new file mode 100644
index 000000000..e8fecf825
--- /dev/null
+++ b/tests/ui/attributes/main-removed-2/main.rs
@@ -0,0 +1,11 @@
+// run-pass
+// aux-build:tokyo.rs
+// compile-flags:--extern tokyo
+// edition:2021
+
+use tokyo::main;
+
+#[main]
+fn main() {
+ panic!("the #[main] macro should replace this with non-panicking code")
+}
diff --git a/tests/ui/attributes/method-attributes.rs b/tests/ui/attributes/method-attributes.rs
new file mode 100644
index 000000000..67439718b
--- /dev/null
+++ b/tests/ui/attributes/method-attributes.rs
@@ -0,0 +1,28 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// pp-exact - Make sure we print all the attributes
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_attrs)]
+
+#[rustc_dummy]
+trait Frobable {
+ #[rustc_dummy]
+ fn frob(&self);
+ #[rustc_dummy]
+ fn defrob(&self);
+}
+
+#[rustc_dummy]
+impl Frobable for isize {
+ #[rustc_dummy]
+ fn frob(&self) {
+ #![rustc_dummy]
+ }
+
+ #[rustc_dummy]
+ fn defrob(&self) {
+ #![rustc_dummy]
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/multiple-invalid.rs b/tests/ui/attributes/multiple-invalid.rs
new file mode 100644
index 000000000..ae044eb84
--- /dev/null
+++ b/tests/ui/attributes/multiple-invalid.rs
@@ -0,0 +1,10 @@
+// This test checks that all expected errors occur when there are multiple invalid attributes
+// on an item.
+
+#[inline]
+//~^ ERROR attribute should be applied to function or closure [E0518]
+#[target_feature(enable = "sse2")]
+//~^ ERROR attribute should be applied to a function
+const FOO: u8 = 0;
+
+fn main() { }
diff --git a/tests/ui/attributes/multiple-invalid.stderr b/tests/ui/attributes/multiple-invalid.stderr
new file mode 100644
index 000000000..a8dba0ba3
--- /dev/null
+++ b/tests/ui/attributes/multiple-invalid.stderr
@@ -0,0 +1,21 @@
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/multiple-invalid.rs:4:1
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+...
+LL | const FOO: u8 = 0;
+ | ------------------ not a function or closure
+
+error: attribute should be applied to a function definition
+ --> $DIR/multiple-invalid.rs:6:1
+ |
+LL | #[target_feature(enable = "sse2")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const FOO: u8 = 0;
+ | ------------------ not a function definition
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0518`.
diff --git a/tests/ui/attributes/nonterminal-expansion.rs b/tests/ui/attributes/nonterminal-expansion.rs
new file mode 100644
index 000000000..97bf225f0
--- /dev/null
+++ b/tests/ui/attributes/nonterminal-expansion.rs
@@ -0,0 +1,18 @@
+// Macros were previously expanded in `Expr` nonterminal tokens, now they are not.
+
+macro_rules! pass_nonterminal {
+ ($n:expr) => {
+ #[repr(align($n))]
+ //~^ ERROR expected unsuffixed literal or identifier, found `n!()`
+ //~| ERROR incorrect `repr(align)` attribute format
+ struct S;
+ };
+}
+
+macro_rules! n {
+ () => { 32 };
+}
+
+pass_nonterminal!(n!());
+
+fn main() {}
diff --git a/tests/ui/attributes/nonterminal-expansion.stderr b/tests/ui/attributes/nonterminal-expansion.stderr
new file mode 100644
index 000000000..52376ac19
--- /dev/null
+++ b/tests/ui/attributes/nonterminal-expansion.stderr
@@ -0,0 +1,25 @@
+error: expected unsuffixed literal or identifier, found `n!()`
+ --> $DIR/nonterminal-expansion.rs:5:22
+ |
+LL | #[repr(align($n))]
+ | ^^
+...
+LL | pass_nonterminal!(n!());
+ | ----------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
+ --> $DIR/nonterminal-expansion.rs:5:16
+ |
+LL | #[repr(align($n))]
+ | ^^^^^^^^^
+...
+LL | pass_nonterminal!(n!());
+ | ----------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `pass_nonterminal` (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 E0693`.
diff --git a/tests/ui/attributes/obsolete-attr.rs b/tests/ui/attributes/obsolete-attr.rs
new file mode 100644
index 000000000..7019abcaf
--- /dev/null
+++ b/tests/ui/attributes/obsolete-attr.rs
@@ -0,0 +1,9 @@
+// Obsolete attributes fall back to unstable custom attributes.
+
+#[ab_isize = "stdcall"] extern "C" {}
+//~^ ERROR cannot find attribute `ab_isize` in this scope
+
+#[fixed_stack_segment] fn f() {}
+//~^ ERROR cannot find attribute `fixed_stack_segment` in this scope
+
+fn main() {}
diff --git a/tests/ui/attributes/obsolete-attr.stderr b/tests/ui/attributes/obsolete-attr.stderr
new file mode 100644
index 000000000..37c1cd0c9
--- /dev/null
+++ b/tests/ui/attributes/obsolete-attr.stderr
@@ -0,0 +1,14 @@
+error: cannot find attribute `fixed_stack_segment` in this scope
+ --> $DIR/obsolete-attr.rs:6:3
+ |
+LL | #[fixed_stack_segment] fn f() {}
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `ab_isize` in this scope
+ --> $DIR/obsolete-attr.rs:3:3
+ |
+LL | #[ab_isize = "stdcall"] extern "C" {}
+ | ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/attributes/suffixed-literal-meta.rs b/tests/ui/attributes/suffixed-literal-meta.rs
new file mode 100644
index 000000000..a6531490c
--- /dev/null
+++ b/tests/ui/attributes/suffixed-literal-meta.rs
@@ -0,0 +1,15 @@
+#![feature(rustc_attrs)]
+
+#[rustc_dummy = 1usize] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1u8] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1u16] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1u32] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1u64] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1isize] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1i8] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1i16] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1i32] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1i64] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1.0f32] //~ ERROR: suffixed literals are not allowed in attributes
+#[rustc_dummy = 1.0f64] //~ ERROR: suffixed literals are not allowed in attributes
+fn main() {}
diff --git a/tests/ui/attributes/suffixed-literal-meta.stderr b/tests/ui/attributes/suffixed-literal-meta.stderr
new file mode 100644
index 000000000..5245ffead
--- /dev/null
+++ b/tests/ui/attributes/suffixed-literal-meta.stderr
@@ -0,0 +1,98 @@
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:3:17
+ |
+LL | #[rustc_dummy = 1usize]
+ | ^^^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:4:17
+ |
+LL | #[rustc_dummy = 1u8]
+ | ^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:5:17
+ |
+LL | #[rustc_dummy = 1u16]
+ | ^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:6:17
+ |
+LL | #[rustc_dummy = 1u32]
+ | ^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:7:17
+ |
+LL | #[rustc_dummy = 1u64]
+ | ^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:8:17
+ |
+LL | #[rustc_dummy = 1isize]
+ | ^^^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:9:17
+ |
+LL | #[rustc_dummy = 1i8]
+ | ^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:10:17
+ |
+LL | #[rustc_dummy = 1i16]
+ | ^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:11:17
+ |
+LL | #[rustc_dummy = 1i32]
+ | ^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:12:17
+ |
+LL | #[rustc_dummy = 1i64]
+ | ^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:13:17
+ |
+LL | #[rustc_dummy = 1.0f32]
+ | ^^^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: suffixed literals are not allowed in attributes
+ --> $DIR/suffixed-literal-meta.rs:14:17
+ |
+LL | #[rustc_dummy = 1.0f64]
+ | ^^^^^^
+ |
+ = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/attributes/tool_attributes.rs b/tests/ui/attributes/tool_attributes.rs
new file mode 100644
index 000000000..be4a10c0e
--- /dev/null
+++ b/tests/ui/attributes/tool_attributes.rs
@@ -0,0 +1,13 @@
+// run-pass
+// Scoped attributes should not trigger an unused attributes lint.
+
+#![deny(unused_attributes)]
+
+fn main() {
+ #[rustfmt::skip]
+ foo ();
+}
+
+fn foo() {
+ assert!(true);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs b/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
new file mode 100644
index 000000000..74fbae035
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
@@ -0,0 +1,33 @@
+#![feature(rustc_private)]
+extern crate libc;
+
+/// So tests don't have to bring libc in scope themselves
+pub enum SignalHandler {
+ Ignore,
+ Default,
+}
+
+/// Helper to assert that [`libc::SIGPIPE`] has the expected signal handler.
+pub fn assert_sigpipe_handler(expected_handler: SignalHandler) {
+ #[cfg(unix)]
+ #[cfg(not(any(
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "horizon",
+ target_os = "android",
+ )))]
+ {
+ let prev = unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN) };
+
+ let expected = match expected_handler {
+ SignalHandler::Ignore => libc::SIG_IGN,
+ SignalHandler::Default => libc::SIG_DFL,
+ };
+ assert_eq!(prev, expected, "expected sigpipe value matches actual value");
+
+ // Unlikely to matter, but restore the old value anyway
+ unsafe {
+ libc::signal(libc::SIGPIPE, prev);
+ };
+ }
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
new file mode 100644
index 000000000..d6d020c52
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+#![unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute cannot be used at crate level
+
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
new file mode 100644
index 000000000..a1fb4d678
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
@@ -0,0 +1,13 @@
+error: `unix_sigpipe` attribute cannot be used at crate level
+ --> $DIR/unix_sigpipe-crate.rs:2:1
+ |
+LL | #![unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: perhaps you meant to use an outer attribute
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
new file mode 100644
index 000000000..294cb3852
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
@@ -0,0 +1,5 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_ign"]
+#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
new file mode 100644
index 000000000..2362c17a0
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
@@ -0,0 +1,14 @@
+error: multiple `unix_sigpipe` attributes
+ --> $DIR/unix_sigpipe-duplicates.rs:4:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unix_sigpipe-duplicates.rs:3:1
+ |
+LL | #[unix_sigpipe = "sig_ign"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs
new file mode 100644
index 000000000..0a42a5b5e
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_ign"]
+fn main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "sig_ign"] is active, so the legacy behavior of ignoring
+ // SIGPIPE shall be in effect
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
new file mode 100644
index 000000000..4f8648077
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"]
+fn main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "inherit"] is active, so SIGPIPE shall NOT be ignored,
+ // instead the default handler shall be installed. (We assume that the
+ // process that runs these tests have the default handler.)
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs
new file mode 100644
index 000000000..b5ebc07a0
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe(inherit)] //~ error: malformed `unix_sigpipe` attribute input
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr
new file mode 100644
index 000000000..59a87e139
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr
@@ -0,0 +1,15 @@
+error: malformed `unix_sigpipe` attribute input
+ --> $DIR/unix_sigpipe-list.rs:3:1
+ |
+LL | #[unix_sigpipe(inherit)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: the following are the possible correct uses
+ |
+LL | #[unix_sigpipe = "inherit|sig_ign|sig_dfl"]
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | #[unix_sigpipe]
+ | ~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
new file mode 100644
index 000000000..cde6719fc
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
@@ -0,0 +1,6 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+fn f() {}
+
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
new file mode 100644
index 000000000..c4b81118c
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+ --> $DIR/unix_sigpipe-non-main-fn.rs:3:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
new file mode 100644
index 000000000..16f727639
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
@@ -0,0 +1,8 @@
+#![feature(unix_sigpipe)]
+
+mod m {
+ #[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on root `fn main()`
+ fn main() {}
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
new file mode 100644
index 000000000..a04f605ed
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on root `fn main()`
+ --> $DIR/unix_sigpipe-non-root-main.rs:4:5
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
new file mode 100644
index 000000000..100b4ce9f
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
@@ -0,0 +1,9 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+fn main() {
+ extern crate sigpipe_utils;
+
+ // SIGPIPE shall be ignored since #[unix_sigpipe = "..."] is not used
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs
new file mode 100644
index 000000000..b5adc2e55
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+fn main() {
+ extern crate sigpipe_utils;
+
+ // Only #![feature(unix_sigpipe)] is enabled, not #[unix_sigpipe = "..."].
+ // This shall not change any behavior, so we still expect SIGPIPE to be
+ // ignored
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
new file mode 100644
index 000000000..6befb9e95
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
@@ -0,0 +1,15 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+#![feature(rustc_attrs)]
+
+#[unix_sigpipe = "sig_dfl"]
+#[rustc_main]
+fn rustc_main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE handler shall be
+ // SIG_DFL. Note that we have a #[rustc_main], but it should still work.
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
new file mode 100644
index 000000000..238c0d57a
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_dfl"]
+fn main() {
+ extern crate sigpipe_utils;
+
+ // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE shall NOT be ignored, instead
+ // the default handler shall be installed
+ sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
new file mode 100644
index 000000000..64fd5ec4f
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
@@ -0,0 +1,6 @@
+#![feature(start)]
+#![feature(unix_sigpipe)]
+
+#[start]
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+fn custom_start(argc: isize, argv: *const *const u8) -> isize { 0 }
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
new file mode 100644
index 000000000..2c9ce479b
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+ --> $DIR/unix_sigpipe-start.rs:5:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
new file mode 100644
index 000000000..a5e47cfeb
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
@@ -0,0 +1,6 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+struct S;
+
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
new file mode 100644
index 000000000..c56ee60bb
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+ --> $DIR/unix_sigpipe-struct.rs:3:1
+ |
+LL | #[unix_sigpipe = "inherit"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
new file mode 100644
index 000000000..4ec25de00
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "wrong"] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
new file mode 100644
index 000000000..a66e45aa2
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
@@ -0,0 +1,8 @@
+error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+ --> $DIR/unix_sigpipe-wrong.rs:3:1
+ |
+LL | #[unix_sigpipe = "wrong"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe.rs
new file mode 100644
index 000000000..7bf1c7350
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe.stderr
new file mode 100644
index 000000000..1b1eda825
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe.stderr
@@ -0,0 +1,8 @@
+error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+ --> $DIR/unix_sigpipe.rs:3:1
+ |
+LL | #[unix_sigpipe]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/unknown-attr.rs b/tests/ui/attributes/unknown-attr.rs
new file mode 100644
index 000000000..70fef04e9
--- /dev/null
+++ b/tests/ui/attributes/unknown-attr.rs
@@ -0,0 +1,12 @@
+// Unknown attributes fall back to unstable custom attributes.
+
+#![feature(custom_inner_attributes)]
+
+#![mutable_doc]
+//~^ ERROR cannot find attribute `mutable_doc` in this scope
+
+#[dance] mod a {}
+//~^ ERROR cannot find attribute `dance` in this scope
+
+#[dance] fn main() {}
+//~^ ERROR cannot find attribute `dance` in this scope
diff --git a/tests/ui/attributes/unknown-attr.stderr b/tests/ui/attributes/unknown-attr.stderr
new file mode 100644
index 000000000..85c227dc8
--- /dev/null
+++ b/tests/ui/attributes/unknown-attr.stderr
@@ -0,0 +1,20 @@
+error: cannot find attribute `mutable_doc` in this scope
+ --> $DIR/unknown-attr.rs:5:4
+ |
+LL | #![mutable_doc]
+ | ^^^^^^^^^^^
+
+error: cannot find attribute `dance` in this scope
+ --> $DIR/unknown-attr.rs:8:3
+ |
+LL | #[dance] mod a {}
+ | ^^^^^
+
+error: cannot find attribute `dance` in this scope
+ --> $DIR/unknown-attr.rs:11:3
+ |
+LL | #[dance] fn main() {}
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/attributes/unnamed-field-attributes-dup.rs b/tests/ui/attributes/unnamed-field-attributes-dup.rs
new file mode 100644
index 000000000..7edfd0337
--- /dev/null
+++ b/tests/ui/attributes/unnamed-field-attributes-dup.rs
@@ -0,0 +1,11 @@
+// Duplicate non-builtin attributes can be used on unnamed fields.
+
+// check-pass
+
+struct S (
+ #[rustfmt::skip]
+ #[rustfmt::skip]
+ u8
+);
+
+fn main() {}
diff --git a/tests/ui/attributes/unnamed-field-attributes-vis.rs b/tests/ui/attributes/unnamed-field-attributes-vis.rs
new file mode 100644
index 000000000..d12155f6d
--- /dev/null
+++ b/tests/ui/attributes/unnamed-field-attributes-vis.rs
@@ -0,0 +1,11 @@
+// Unnamed fields don't lose their visibility due to non-builtin attributes on them.
+
+// check-pass
+
+mod m {
+ pub struct S(#[rustfmt::skip] pub u8);
+}
+
+fn main() {
+ m::S(0);
+}
diff --git a/tests/ui/attributes/unnamed-field-attributes.rs b/tests/ui/attributes/unnamed-field-attributes.rs
new file mode 100644
index 000000000..93f364047
--- /dev/null
+++ b/tests/ui/attributes/unnamed-field-attributes.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+struct S(
+ #[rustfmt::skip] u8,
+ u16,
+ #[rustfmt::skip] u32,
+);
+
+fn main() {}
diff --git a/tests/ui/attributes/unrestricted-attribute-tokens.rs b/tests/ui/attributes/unrestricted-attribute-tokens.rs
new file mode 100644
index 000000000..e31bc91a0
--- /dev/null
+++ b/tests/ui/attributes/unrestricted-attribute-tokens.rs
@@ -0,0 +1,8 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![feature(rustc_attrs)]
+
+#[rustc_dummy(a b c d)]
+#[rustc_dummy[a b c d]]
+#[rustc_dummy{a b c d}]
+fn main() {}
diff --git a/tests/ui/attributes/unused-item-in-attr.rs b/tests/ui/attributes/unused-item-in-attr.rs
new file mode 100644
index 000000000..70dcd5413
--- /dev/null
+++ b/tests/ui/attributes/unused-item-in-attr.rs
@@ -0,0 +1,6 @@
+#[w = { extern crate alloc; }]
+//~^ ERROR unexpected expression: `{
+//~| ERROR cannot find attribute `w` in this scope
+fn f() {}
+
+fn main() {}
diff --git a/tests/ui/attributes/unused-item-in-attr.stderr b/tests/ui/attributes/unused-item-in-attr.stderr
new file mode 100644
index 000000000..92a8f5858
--- /dev/null
+++ b/tests/ui/attributes/unused-item-in-attr.stderr
@@ -0,0 +1,16 @@
+error: unexpected expression: `{
+ extern crate alloc;
+ }`
+ --> $DIR/unused-item-in-attr.rs:1:7
+ |
+LL | #[w = { extern crate alloc; }]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `w` in this scope
+ --> $DIR/unused-item-in-attr.rs:1:3
+ |
+LL | #[w = { extern crate alloc; }]
+ | ^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/attributes/used_with_arg.rs b/tests/ui/attributes/used_with_arg.rs
new file mode 100644
index 000000000..ad80ff53f
--- /dev/null
+++ b/tests/ui/attributes/used_with_arg.rs
@@ -0,0 +1,19 @@
+#![feature(used_with_arg)]
+
+#[used(linker)]
+static mut USED_LINKER: [usize; 1] = [0];
+
+#[used(compiler)]
+static mut USED_COMPILER: [usize; 1] = [0];
+
+#[used(compiler)] //~ ERROR `used(compiler)` and `used(linker)` can't be used together
+#[used(linker)]
+static mut USED_COMPILER_LINKER2: [usize; 1] = [0];
+
+#[used(compiler)] //~ ERROR `used(compiler)` and `used(linker)` can't be used together
+#[used(linker)]
+#[used(compiler)]
+#[used(linker)]
+static mut USED_COMPILER_LINKER3: [usize; 1] = [0];
+
+fn main() {}
diff --git a/tests/ui/attributes/used_with_arg.stderr b/tests/ui/attributes/used_with_arg.stderr
new file mode 100644
index 000000000..440e5c4a5
--- /dev/null
+++ b/tests/ui/attributes/used_with_arg.stderr
@@ -0,0 +1,18 @@
+error: `used(compiler)` and `used(linker)` can't be used together
+ --> $DIR/used_with_arg.rs:9:1
+ |
+LL | #[used(compiler)]
+ | ^^^^^^^^^^^^^^^^^
+LL | #[used(linker)]
+ | ^^^^^^^^^^^^^^^
+
+error: `used(compiler)` and `used(linker)` can't be used together
+ --> $DIR/used_with_arg.rs:13:1
+ |
+LL | #[used(compiler)]
+ | ^^^^^^^^^^^^^^^^^
+LL | #[used(linker)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/attributes/used_with_arg_no_mangle.rs b/tests/ui/attributes/used_with_arg_no_mangle.rs
new file mode 100644
index 000000000..d0bbe76ef
--- /dev/null
+++ b/tests/ui/attributes/used_with_arg_no_mangle.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(used_with_arg)]
+
+#[used(linker)]
+#[no_mangle] // accidentally detected as `used(compiler)`
+pub static GLOB: usize = 0;
+
+fn main() {}
diff --git a/tests/ui/attributes/used_with_multi_args.rs b/tests/ui/attributes/used_with_multi_args.rs
new file mode 100644
index 000000000..2e17fcfd7
--- /dev/null
+++ b/tests/ui/attributes/used_with_multi_args.rs
@@ -0,0 +1,6 @@
+#![feature(used_with_arg)]
+
+#[used(compiler, linker)] //~ expected `used`, `used(compiler)` or `used(linker)`
+static mut USED_COMPILER_LINKER: [usize; 1] = [0];
+
+fn main() {}
diff --git a/tests/ui/attributes/used_with_multi_args.stderr b/tests/ui/attributes/used_with_multi_args.stderr
new file mode 100644
index 000000000..c93aafcfc
--- /dev/null
+++ b/tests/ui/attributes/used_with_multi_args.stderr
@@ -0,0 +1,8 @@
+error: expected `used`, `used(compiler)` or `used(linker)`
+ --> $DIR/used_with_multi_args.rs:3:1
+ |
+LL | #[used(compiler, linker)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/attributes/variant-attributes.rs b/tests/ui/attributes/variant-attributes.rs
new file mode 100644
index 000000000..ffcdeb52a
--- /dev/null
+++ b/tests/ui/attributes/variant-attributes.rs
@@ -0,0 +1,37 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// pp-exact - Make sure we actually print the attributes
+// pretty-expanded FIXME #23616
+
+#![allow(non_camel_case_types)]
+#![feature(rustc_attrs)]
+
+enum crew_of_enterprise_d {
+
+ #[rustc_dummy]
+ jean_luc_picard,
+
+ #[rustc_dummy]
+ william_t_riker,
+
+ #[rustc_dummy]
+ beverly_crusher,
+
+ #[rustc_dummy]
+ deanna_troi,
+
+ #[rustc_dummy]
+ data,
+
+ #[rustc_dummy]
+ worf,
+
+ #[rustc_dummy]
+ geordi_la_forge,
+}
+
+fn boldly_go(_crew_member: crew_of_enterprise_d, _where: String) { }
+
+fn main() {
+ boldly_go(crew_of_enterprise_d::worf,
+ "where no one has gone before".to_string());
+}
diff --git a/tests/ui/attributes/z-crate-attr.rs b/tests/ui/attributes/z-crate-attr.rs
new file mode 100644
index 000000000..1021774fc
--- /dev/null
+++ b/tests/ui/attributes/z-crate-attr.rs
@@ -0,0 +1,12 @@
+// run-pass
+// This test checks if an unstable feature is enabled with the -Zcrate-attr=feature(foo) flag. If
+// the exact feature used here is causing problems feel free to replace it with another
+// perma-unstable feature.
+
+// compile-flags: -Zcrate-attr=feature(abi_unadjusted)
+
+#![allow(dead_code)]
+
+extern "unadjusted" fn foo() {}
+
+fn main() {}