From a839b071f7988e77040474dc870ba16b77666a8f Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Sat, 5 Jul 2025 15:58:04 +0100 Subject: Use `object` crate from crates.io to fix windows build error --- compiler/rustc_codegen_gcc/Cargo.lock | 10 ++++++++++ compiler/rustc_codegen_gcc/Cargo.toml | 1 + compiler/rustc_codegen_gcc/src/lib.rs | 1 - 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index b20c181a8cb..7f35c1a80bd 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -143,6 +143,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.20.2" @@ -179,6 +188,7 @@ dependencies = [ "boml", "gccjit", "lang_tester", + "object", "tempfile", ] diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml index c284e3f060b..05b0431b6ba 100644 --- a/compiler/rustc_codegen_gcc/Cargo.toml +++ b/compiler/rustc_codegen_gcc/Cargo.toml @@ -22,6 +22,7 @@ master = ["gccjit/master"] default = ["master"] [dependencies] +object = { version = "0.37.0", default-features = false, features = ["std", "read"] } gccjit = "2.7" #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index a912678ef2a..56afdd55bf9 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -27,7 +27,6 @@ #![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)] // Some "regular" crates we want to share with rustc -extern crate object; extern crate smallvec; // FIXME(antoyo): clippy bug: remove the #[allow] when it's fixed. #[allow(unused_extern_crates)] -- cgit 1.4.1-3-g733a5 From ea7b7568759e071f50060a2d76a4619de6c42c2f Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Sat, 5 Jul 2025 17:23:39 +0100 Subject: Make tempfile a normal dependency --- compiler/rustc_codegen_gcc/Cargo.toml | 2 +- compiler/rustc_codegen_gcc/src/lib.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml index 05b0431b6ba..193348d1ef6 100644 --- a/compiler/rustc_codegen_gcc/Cargo.toml +++ b/compiler/rustc_codegen_gcc/Cargo.toml @@ -23,6 +23,7 @@ default = ["master"] [dependencies] object = { version = "0.37.0", default-features = false, features = ["std", "read"] } +tempfile = "3.20" gccjit = "2.7" #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } @@ -32,7 +33,6 @@ gccjit = "2.7" [dev-dependencies] boml = "0.3.1" lang_tester = "0.8.0" -tempfile = "3.20" [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 56afdd55bf9..1a6eec0ed0b 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -26,11 +26,9 @@ #![deny(clippy::pattern_type_mismatch)] #![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)] -// Some "regular" crates we want to share with rustc +// These crates are pulled from the sysroot because they are part of +// rustc's public API, so we need to ensure version compatibility. extern crate smallvec; -// FIXME(antoyo): clippy bug: remove the #[allow] when it's fixed. -#[allow(unused_extern_crates)] -extern crate tempfile; #[macro_use] extern crate tracing; -- cgit 1.4.1-3-g733a5 From 6d64306df1d834966a23a27c085c043214668181 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 5 Jul 2025 16:52:59 -0700 Subject: Move macro tests in `parser` into `macro` directory The `macro` directory contains most of the macro tests, but not all of them; move the remainder into `macro`. --- .../ui/parser/break-in-unlabeled-block-in-macro.rs | 43 -------------- .../break-in-unlabeled-block-in-macro.stderr | 69 ---------------------- ...een-macro-without-exclamation-mark-and-array.rs | 3 - ...macro-without-exclamation-mark-and-array.stderr | 8 --- .../ui/parser/extern-abi-from-mac-literal-frag.rs | 51 ---------------- tests/ui/parser/lit-err-in-macro.rs | 10 ---- tests/ui/parser/lit-err-in-macro.stderr | 20 ------- tests/ui/parser/macro-bad-delimiter-ident.rs | 3 - tests/ui/parser/macro-bad-delimiter-ident.stderr | 8 --- tests/ui/parser/macro-braces-dot-question.rs | 11 ---- tests/ui/parser/macro-keyword.rs | 5 -- tests/ui/parser/macro-keyword.stderr | 13 ---- .../parser/macro-mismatched-delim-brace-paren.rs | 7 --- .../macro-mismatched-delim-brace-paren.stderr | 11 ---- .../parser/macro-mismatched-delim-paren-brace.rs | 5 -- .../macro-mismatched-delim-paren-brace.stderr | 22 ------- .../macro/break-in-unlabeled-block-in-macro.rs | 43 ++++++++++++++ .../macro/break-in-unlabeled-block-in-macro.stderr | 69 ++++++++++++++++++++++ ...een-macro-without-exclamation-mark-and-array.rs | 3 + ...macro-without-exclamation-mark-and-array.stderr | 8 +++ .../macro/extern-abi-from-mac-literal-frag.rs | 51 ++++++++++++++++ tests/ui/parser/macro/lit-err-in-macro.rs | 10 ++++ tests/ui/parser/macro/lit-err-in-macro.stderr | 20 +++++++ tests/ui/parser/macro/macro-bad-delimiter-ident.rs | 3 + .../parser/macro/macro-bad-delimiter-ident.stderr | 8 +++ tests/ui/parser/macro/macro-braces-dot-question.rs | 11 ++++ tests/ui/parser/macro/macro-keyword.rs | 5 ++ tests/ui/parser/macro/macro-keyword.stderr | 13 ++++ .../macro/macro-mismatched-delim-brace-paren.rs | 7 +++ .../macro-mismatched-delim-brace-paren.stderr | 11 ++++ .../macro/macro-mismatched-delim-paren-brace.rs | 5 ++ .../macro-mismatched-delim-paren-brace.stderr | 22 +++++++ tests/ui/parser/macro/macros-no-semicolon-items.rs | 15 +++++ .../parser/macro/macros-no-semicolon-items.stderr | 48 +++++++++++++++ tests/ui/parser/macro/macros-no-semicolon.rs | 5 ++ tests/ui/parser/macro/macros-no-semicolon.stderr | 18 ++++++ tests/ui/parser/macro/mbe_missing_right_paren.rs | 3 + .../ui/parser/macro/mbe_missing_right_paren.stderr | 10 ++++ tests/ui/parser/macro/misspelled-macro-rules.fixed | 13 ++++ tests/ui/parser/macro/misspelled-macro-rules.rs | 13 ++++ .../ui/parser/macro/misspelled-macro-rules.stderr | 10 ++++ tests/ui/parser/macro/pub-method-macro.rs | 23 ++++++++ tests/ui/parser/macro/pub-method-macro.stderr | 15 +++++ .../ui/parser/macro/semi-after-closure-in-macro.rs | 14 +++++ .../macro/trailing-question-in-macro-type.rs | 14 +++++ .../macro/trailing-question-in-macro-type.stderr | 9 +++ tests/ui/parser/macros-no-semicolon-items.rs | 15 ----- tests/ui/parser/macros-no-semicolon-items.stderr | 48 --------------- tests/ui/parser/macros-no-semicolon.rs | 5 -- tests/ui/parser/macros-no-semicolon.stderr | 18 ------ tests/ui/parser/mbe_missing_right_paren.rs | 3 - tests/ui/parser/mbe_missing_right_paren.stderr | 10 ---- tests/ui/parser/misspelled-macro-rules.fixed | 13 ---- tests/ui/parser/misspelled-macro-rules.rs | 13 ---- tests/ui/parser/misspelled-macro-rules.stderr | 10 ---- tests/ui/parser/pub-method-macro.rs | 23 -------- tests/ui/parser/pub-method-macro.stderr | 15 ----- tests/ui/parser/semi-after-closure-in-macro.rs | 14 ----- tests/ui/parser/trailing-question-in-macro-type.rs | 14 ----- .../parser/trailing-question-in-macro-type.stderr | 9 --- 60 files changed, 499 insertions(+), 499 deletions(-) delete mode 100644 tests/ui/parser/break-in-unlabeled-block-in-macro.rs delete mode 100644 tests/ui/parser/break-in-unlabeled-block-in-macro.stderr delete mode 100644 tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs delete mode 100644 tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr delete mode 100644 tests/ui/parser/extern-abi-from-mac-literal-frag.rs delete mode 100644 tests/ui/parser/lit-err-in-macro.rs delete mode 100644 tests/ui/parser/lit-err-in-macro.stderr delete mode 100644 tests/ui/parser/macro-bad-delimiter-ident.rs delete mode 100644 tests/ui/parser/macro-bad-delimiter-ident.stderr delete mode 100644 tests/ui/parser/macro-braces-dot-question.rs delete mode 100644 tests/ui/parser/macro-keyword.rs delete mode 100644 tests/ui/parser/macro-keyword.stderr delete mode 100644 tests/ui/parser/macro-mismatched-delim-brace-paren.rs delete mode 100644 tests/ui/parser/macro-mismatched-delim-brace-paren.stderr delete mode 100644 tests/ui/parser/macro-mismatched-delim-paren-brace.rs delete mode 100644 tests/ui/parser/macro-mismatched-delim-paren-brace.stderr create mode 100644 tests/ui/parser/macro/break-in-unlabeled-block-in-macro.rs create mode 100644 tests/ui/parser/macro/break-in-unlabeled-block-in-macro.stderr create mode 100644 tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs create mode 100644 tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr create mode 100644 tests/ui/parser/macro/extern-abi-from-mac-literal-frag.rs create mode 100644 tests/ui/parser/macro/lit-err-in-macro.rs create mode 100644 tests/ui/parser/macro/lit-err-in-macro.stderr create mode 100644 tests/ui/parser/macro/macro-bad-delimiter-ident.rs create mode 100644 tests/ui/parser/macro/macro-bad-delimiter-ident.stderr create mode 100644 tests/ui/parser/macro/macro-braces-dot-question.rs create mode 100644 tests/ui/parser/macro/macro-keyword.rs create mode 100644 tests/ui/parser/macro/macro-keyword.stderr create mode 100644 tests/ui/parser/macro/macro-mismatched-delim-brace-paren.rs create mode 100644 tests/ui/parser/macro/macro-mismatched-delim-brace-paren.stderr create mode 100644 tests/ui/parser/macro/macro-mismatched-delim-paren-brace.rs create mode 100644 tests/ui/parser/macro/macro-mismatched-delim-paren-brace.stderr create mode 100644 tests/ui/parser/macro/macros-no-semicolon-items.rs create mode 100644 tests/ui/parser/macro/macros-no-semicolon-items.stderr create mode 100644 tests/ui/parser/macro/macros-no-semicolon.rs create mode 100644 tests/ui/parser/macro/macros-no-semicolon.stderr create mode 100644 tests/ui/parser/macro/mbe_missing_right_paren.rs create mode 100644 tests/ui/parser/macro/mbe_missing_right_paren.stderr create mode 100644 tests/ui/parser/macro/misspelled-macro-rules.fixed create mode 100644 tests/ui/parser/macro/misspelled-macro-rules.rs create mode 100644 tests/ui/parser/macro/misspelled-macro-rules.stderr create mode 100644 tests/ui/parser/macro/pub-method-macro.rs create mode 100644 tests/ui/parser/macro/pub-method-macro.stderr create mode 100644 tests/ui/parser/macro/semi-after-closure-in-macro.rs create mode 100644 tests/ui/parser/macro/trailing-question-in-macro-type.rs create mode 100644 tests/ui/parser/macro/trailing-question-in-macro-type.stderr delete mode 100644 tests/ui/parser/macros-no-semicolon-items.rs delete mode 100644 tests/ui/parser/macros-no-semicolon-items.stderr delete mode 100644 tests/ui/parser/macros-no-semicolon.rs delete mode 100644 tests/ui/parser/macros-no-semicolon.stderr delete mode 100644 tests/ui/parser/mbe_missing_right_paren.rs delete mode 100644 tests/ui/parser/mbe_missing_right_paren.stderr delete mode 100644 tests/ui/parser/misspelled-macro-rules.fixed delete mode 100644 tests/ui/parser/misspelled-macro-rules.rs delete mode 100644 tests/ui/parser/misspelled-macro-rules.stderr delete mode 100644 tests/ui/parser/pub-method-macro.rs delete mode 100644 tests/ui/parser/pub-method-macro.stderr delete mode 100644 tests/ui/parser/semi-after-closure-in-macro.rs delete mode 100644 tests/ui/parser/trailing-question-in-macro-type.rs delete mode 100644 tests/ui/parser/trailing-question-in-macro-type.stderr diff --git a/tests/ui/parser/break-in-unlabeled-block-in-macro.rs b/tests/ui/parser/break-in-unlabeled-block-in-macro.rs deleted file mode 100644 index eecc0026b12..00000000000 --- a/tests/ui/parser/break-in-unlabeled-block-in-macro.rs +++ /dev/null @@ -1,43 +0,0 @@ -macro_rules! foo { - () => { - break (); //~ ERROR `break` outside of a loop or labeled block - }; - ($e: expr) => { - break $e; //~ ERROR `break` outside of a loop or labeled block - }; - (stmt $s: stmt) => { - $s - }; - (@ $e: expr) => { - { break $e; } //~ ERROR `break` outside of a loop or labeled block - }; - (=> $s: stmt) => { - { $s } - }; -} - -fn main() { - { - foo!(); - } - { - foo!(()); - } - { - foo!(stmt break ()); //~ ERROR `break` outside of a loop or labeled block - } - { - foo!(@ ()); - } - { - foo!(=> break ()); //~ ERROR `break` outside of a loop or labeled block - } - { - macro_rules! bar { - () => { - break () //~ ERROR `break` outside of a loop or labeled block - }; - } - bar!() - } -} diff --git a/tests/ui/parser/break-in-unlabeled-block-in-macro.stderr b/tests/ui/parser/break-in-unlabeled-block-in-macro.stderr deleted file mode 100644 index 2f46cb36750..00000000000 --- a/tests/ui/parser/break-in-unlabeled-block-in-macro.stderr +++ /dev/null @@ -1,69 +0,0 @@ -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-in-unlabeled-block-in-macro.rs:3:9 - | -LL | break (); - | ^^^^^^^^ cannot `break` outside of a loop or labeled block -... -LL | foo!(); - | ------ in this macro invocation - | - = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-in-unlabeled-block-in-macro.rs:6:9 - | -LL | break $e; - | ^^^^^^^^ cannot `break` outside of a loop or labeled block -... -LL | foo!(()); - | -------- in this macro invocation - | - = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-in-unlabeled-block-in-macro.rs:33:17 - | -LL | foo!(=> break ()); - | ^^^^^^^^ cannot `break` outside of a loop or labeled block - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-in-unlabeled-block-in-macro.rs:38:17 - | -LL | break () - | ^^^^^^^^ cannot `break` outside of a loop or labeled block -... -LL | bar!() - | ------ in this macro invocation - | - = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-in-unlabeled-block-in-macro.rs:12:11 - | -LL | { break $e; } - | ^^^^^^^^ cannot `break` outside of a loop or labeled block -... -LL | foo!(@ ()); - | ---------- in this macro invocation - | - = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider labeling this block to be able to break within it - | -LL | 'block: { break 'block $e; } - | +++++++ ++++++ - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-in-unlabeled-block-in-macro.rs:27:19 - | -LL | foo!(stmt break ()); - | ^^^^^^^^ cannot `break` outside of a loop or labeled block - | -help: consider labeling this block to be able to break within it - | -LL ~ 'block: { -LL ~ foo!(stmt break 'block ()); - | - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs b/tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs deleted file mode 100644 index d6f7981813f..00000000000 --- a/tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let _x = vec[1, 2, 3]; //~ ERROR expected one of `.`, `?`, `]`, or an operator -} diff --git a/tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr b/tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr deleted file mode 100644 index 2796312f4ad..00000000000 --- a/tests/ui/parser/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `.`, `?`, `]`, or an operator, found `,` - --> $DIR/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs:2:19 - | -LL | let _x = vec[1, 2, 3]; - | ^ expected one of `.`, `?`, `]`, or an operator - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/extern-abi-from-mac-literal-frag.rs b/tests/ui/parser/extern-abi-from-mac-literal-frag.rs deleted file mode 100644 index 12b6c98705c..00000000000 --- a/tests/ui/parser/extern-abi-from-mac-literal-frag.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow(clashing_extern_declarations)] -//@ check-pass - -// In this test we check that the parser accepts an ABI string when it -// comes from a macro `literal` or `expr` fragment as opposed to a hardcoded string. - -fn main() {} - -macro_rules! abi_from_lit_frag { - ($abi:literal) => { - extern $abi { - fn _import(); - } - - unsafe extern $abi {} - - extern $abi fn _export() {} - - type _PTR = extern $abi fn(); - } -} - -macro_rules! abi_from_expr_frag { - ($abi:expr) => { - extern $abi { - fn _import(); - } - - unsafe extern $abi {} - - extern $abi fn _export() {} - - type _PTR = extern $abi fn(); - }; -} - -mod rust { - abi_from_lit_frag!("Rust"); -} - -mod c { - abi_from_lit_frag!("C"); -} - -mod rust_expr { - abi_from_expr_frag!("Rust"); -} - -mod c_expr { - abi_from_expr_frag!("C"); -} diff --git a/tests/ui/parser/lit-err-in-macro.rs b/tests/ui/parser/lit-err-in-macro.rs deleted file mode 100644 index ca117ac4a15..00000000000 --- a/tests/ui/parser/lit-err-in-macro.rs +++ /dev/null @@ -1,10 +0,0 @@ -macro_rules! f { - ($abi:literal) => { - extern $abi fn f() {} //~ WARN missing_abi - } -} - -f!("Foo"__); -//~^ ERROR suffixes on string literals are invalid - -fn main() {} diff --git a/tests/ui/parser/lit-err-in-macro.stderr b/tests/ui/parser/lit-err-in-macro.stderr deleted file mode 100644 index 08fe58643d4..00000000000 --- a/tests/ui/parser/lit-err-in-macro.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: suffixes on string literals are invalid - --> $DIR/lit-err-in-macro.rs:7:4 - | -LL | f!("Foo"__); - | ^^^^^^^ invalid suffix `__` - -warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/lit-err-in-macro.rs:3:9 - | -LL | extern $abi fn f() {} - | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` -... -LL | f!("Foo"__); - | ----------- in this macro invocation - | - = note: `#[warn(missing_abi)]` on by default - = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/parser/macro-bad-delimiter-ident.rs b/tests/ui/parser/macro-bad-delimiter-ident.rs deleted file mode 100644 index f461f06b4dc..00000000000 --- a/tests/ui/parser/macro-bad-delimiter-ident.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - foo! bar < //~ ERROR expected one of `(`, `[`, or `{`, found `bar` -} diff --git a/tests/ui/parser/macro-bad-delimiter-ident.stderr b/tests/ui/parser/macro-bad-delimiter-ident.stderr deleted file mode 100644 index 06f72cdecf2..00000000000 --- a/tests/ui/parser/macro-bad-delimiter-ident.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `(`, `[`, or `{`, found `bar` - --> $DIR/macro-bad-delimiter-ident.rs:2:10 - | -LL | foo! bar < - | ^^^ expected one of `(`, `[`, or `{` - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/macro-braces-dot-question.rs b/tests/ui/parser/macro-braces-dot-question.rs deleted file mode 100644 index 9b070f201b5..00000000000 --- a/tests/ui/parser/macro-braces-dot-question.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ check-pass - -use std::io::Write; - -fn main() -> Result<(), std::io::Error> { - vec! { 1, 2, 3 }.len(); - write! { vec![], "" }?; - println!{""} - [0]; // separate statement, not indexing into the result of println. - Ok(()) -} diff --git a/tests/ui/parser/macro-keyword.rs b/tests/ui/parser/macro-keyword.rs deleted file mode 100644 index 58489fb2c51..00000000000 --- a/tests/ui/parser/macro-keyword.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn macro() { //~ ERROR expected identifier, found reserved keyword `macro` -} - -pub fn main() { -} diff --git a/tests/ui/parser/macro-keyword.stderr b/tests/ui/parser/macro-keyword.stderr deleted file mode 100644 index bfe89e320e0..00000000000 --- a/tests/ui/parser/macro-keyword.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: expected identifier, found reserved keyword `macro` - --> $DIR/macro-keyword.rs:1:4 - | -LL | fn macro() { - | ^^^^^ expected identifier, found reserved keyword - | -help: escape `macro` to use it as an identifier - | -LL | fn r#macro() { - | ++ - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/macro-mismatched-delim-brace-paren.rs b/tests/ui/parser/macro-mismatched-delim-brace-paren.rs deleted file mode 100644 index 404aa7b806a..00000000000 --- a/tests/ui/parser/macro-mismatched-delim-brace-paren.rs +++ /dev/null @@ -1,7 +0,0 @@ -macro_rules! foo { ($($tt:tt)*) => () } - -fn main() { - foo! { - bar, "baz", 1, 2.0 - ) //~ ERROR mismatched closing delimiter -} diff --git a/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr b/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr deleted file mode 100644 index f9a3072229f..00000000000 --- a/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: mismatched closing delimiter: `)` - --> $DIR/macro-mismatched-delim-brace-paren.rs:4:10 - | -LL | foo! { - | ^ unclosed delimiter -LL | bar, "baz", 1, 2.0 -LL | ) - | ^ mismatched closing delimiter - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/macro-mismatched-delim-paren-brace.rs b/tests/ui/parser/macro-mismatched-delim-paren-brace.rs deleted file mode 100644 index 1a1b9edfbcb..00000000000 --- a/tests/ui/parser/macro-mismatched-delim-paren-brace.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - foo! ( - bar, "baz", 1, 2.0 - } //~ ERROR mismatched closing delimiter -} //~ ERROR unexpected closing delimiter: `}` diff --git a/tests/ui/parser/macro-mismatched-delim-paren-brace.stderr b/tests/ui/parser/macro-mismatched-delim-paren-brace.stderr deleted file mode 100644 index 34217e21ae9..00000000000 --- a/tests/ui/parser/macro-mismatched-delim-paren-brace.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: mismatched closing delimiter: `}` - --> $DIR/macro-mismatched-delim-paren-brace.rs:2:10 - | -LL | foo! ( - | ^ unclosed delimiter -LL | bar, "baz", 1, 2.0 -LL | } - | ^ mismatched closing delimiter - -error: unexpected closing delimiter: `}` - --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1 - | -LL | fn main() { - | - this delimiter might not be properly closed... -... -LL | } - | - ...as it matches this but it has different indentation -LL | } - | ^ unexpected closing delimiter - -error: aborting due to 2 previous errors - diff --git a/tests/ui/parser/macro/break-in-unlabeled-block-in-macro.rs b/tests/ui/parser/macro/break-in-unlabeled-block-in-macro.rs new file mode 100644 index 00000000000..eecc0026b12 --- /dev/null +++ b/tests/ui/parser/macro/break-in-unlabeled-block-in-macro.rs @@ -0,0 +1,43 @@ +macro_rules! foo { + () => { + break (); //~ ERROR `break` outside of a loop or labeled block + }; + ($e: expr) => { + break $e; //~ ERROR `break` outside of a loop or labeled block + }; + (stmt $s: stmt) => { + $s + }; + (@ $e: expr) => { + { break $e; } //~ ERROR `break` outside of a loop or labeled block + }; + (=> $s: stmt) => { + { $s } + }; +} + +fn main() { + { + foo!(); + } + { + foo!(()); + } + { + foo!(stmt break ()); //~ ERROR `break` outside of a loop or labeled block + } + { + foo!(@ ()); + } + { + foo!(=> break ()); //~ ERROR `break` outside of a loop or labeled block + } + { + macro_rules! bar { + () => { + break () //~ ERROR `break` outside of a loop or labeled block + }; + } + bar!() + } +} diff --git a/tests/ui/parser/macro/break-in-unlabeled-block-in-macro.stderr b/tests/ui/parser/macro/break-in-unlabeled-block-in-macro.stderr new file mode 100644 index 00000000000..2f46cb36750 --- /dev/null +++ b/tests/ui/parser/macro/break-in-unlabeled-block-in-macro.stderr @@ -0,0 +1,69 @@ +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:3:9 + | +LL | break (); + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | foo!(); + | ------ in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:6:9 + | +LL | break $e; + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | foo!(()); + | -------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:33:17 + | +LL | foo!(=> break ()); + | ^^^^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:38:17 + | +LL | break () + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | bar!() + | ------ in this macro invocation + | + = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:12:11 + | +LL | { break $e; } + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | foo!(@ ()); + | ---------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider labeling this block to be able to break within it + | +LL | 'block: { break 'block $e; } + | +++++++ ++++++ + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:27:19 + | +LL | foo!(stmt break ()); + | ^^^^^^^^ cannot `break` outside of a loop or labeled block + | +help: consider labeling this block to be able to break within it + | +LL ~ 'block: { +LL ~ foo!(stmt break 'block ()); + | + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs b/tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs new file mode 100644 index 00000000000..d6f7981813f --- /dev/null +++ b/tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs @@ -0,0 +1,3 @@ +fn main() { + let _x = vec[1, 2, 3]; //~ ERROR expected one of `.`, `?`, `]`, or an operator +} diff --git a/tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr b/tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr new file mode 100644 index 00000000000..2796312f4ad --- /dev/null +++ b/tests/ui/parser/macro/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `?`, `]`, or an operator, found `,` + --> $DIR/do-not-suggest-semicolon-between-macro-without-exclamation-mark-and-array.rs:2:19 + | +LL | let _x = vec[1, 2, 3]; + | ^ expected one of `.`, `?`, `]`, or an operator + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/extern-abi-from-mac-literal-frag.rs b/tests/ui/parser/macro/extern-abi-from-mac-literal-frag.rs new file mode 100644 index 00000000000..12b6c98705c --- /dev/null +++ b/tests/ui/parser/macro/extern-abi-from-mac-literal-frag.rs @@ -0,0 +1,51 @@ +#![allow(clashing_extern_declarations)] +//@ check-pass + +// In this test we check that the parser accepts an ABI string when it +// comes from a macro `literal` or `expr` fragment as opposed to a hardcoded string. + +fn main() {} + +macro_rules! abi_from_lit_frag { + ($abi:literal) => { + extern $abi { + fn _import(); + } + + unsafe extern $abi {} + + extern $abi fn _export() {} + + type _PTR = extern $abi fn(); + } +} + +macro_rules! abi_from_expr_frag { + ($abi:expr) => { + extern $abi { + fn _import(); + } + + unsafe extern $abi {} + + extern $abi fn _export() {} + + type _PTR = extern $abi fn(); + }; +} + +mod rust { + abi_from_lit_frag!("Rust"); +} + +mod c { + abi_from_lit_frag!("C"); +} + +mod rust_expr { + abi_from_expr_frag!("Rust"); +} + +mod c_expr { + abi_from_expr_frag!("C"); +} diff --git a/tests/ui/parser/macro/lit-err-in-macro.rs b/tests/ui/parser/macro/lit-err-in-macro.rs new file mode 100644 index 00000000000..ca117ac4a15 --- /dev/null +++ b/tests/ui/parser/macro/lit-err-in-macro.rs @@ -0,0 +1,10 @@ +macro_rules! f { + ($abi:literal) => { + extern $abi fn f() {} //~ WARN missing_abi + } +} + +f!("Foo"__); +//~^ ERROR suffixes on string literals are invalid + +fn main() {} diff --git a/tests/ui/parser/macro/lit-err-in-macro.stderr b/tests/ui/parser/macro/lit-err-in-macro.stderr new file mode 100644 index 00000000000..08fe58643d4 --- /dev/null +++ b/tests/ui/parser/macro/lit-err-in-macro.stderr @@ -0,0 +1,20 @@ +error: suffixes on string literals are invalid + --> $DIR/lit-err-in-macro.rs:7:4 + | +LL | f!("Foo"__); + | ^^^^^^^ invalid suffix `__` + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/lit-err-in-macro.rs:3:9 + | +LL | extern $abi fn f() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` +... +LL | f!("Foo"__); + | ----------- in this macro invocation + | + = note: `#[warn(missing_abi)]` on by default + = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/parser/macro/macro-bad-delimiter-ident.rs b/tests/ui/parser/macro/macro-bad-delimiter-ident.rs new file mode 100644 index 00000000000..f461f06b4dc --- /dev/null +++ b/tests/ui/parser/macro/macro-bad-delimiter-ident.rs @@ -0,0 +1,3 @@ +fn main() { + foo! bar < //~ ERROR expected one of `(`, `[`, or `{`, found `bar` +} diff --git a/tests/ui/parser/macro/macro-bad-delimiter-ident.stderr b/tests/ui/parser/macro/macro-bad-delimiter-ident.stderr new file mode 100644 index 00000000000..06f72cdecf2 --- /dev/null +++ b/tests/ui/parser/macro/macro-bad-delimiter-ident.stderr @@ -0,0 +1,8 @@ +error: expected one of `(`, `[`, or `{`, found `bar` + --> $DIR/macro-bad-delimiter-ident.rs:2:10 + | +LL | foo! bar < + | ^^^ expected one of `(`, `[`, or `{` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/macro-braces-dot-question.rs b/tests/ui/parser/macro/macro-braces-dot-question.rs new file mode 100644 index 00000000000..9b070f201b5 --- /dev/null +++ b/tests/ui/parser/macro/macro-braces-dot-question.rs @@ -0,0 +1,11 @@ +//@ check-pass + +use std::io::Write; + +fn main() -> Result<(), std::io::Error> { + vec! { 1, 2, 3 }.len(); + write! { vec![], "" }?; + println!{""} + [0]; // separate statement, not indexing into the result of println. + Ok(()) +} diff --git a/tests/ui/parser/macro/macro-keyword.rs b/tests/ui/parser/macro/macro-keyword.rs new file mode 100644 index 00000000000..58489fb2c51 --- /dev/null +++ b/tests/ui/parser/macro/macro-keyword.rs @@ -0,0 +1,5 @@ +fn macro() { //~ ERROR expected identifier, found reserved keyword `macro` +} + +pub fn main() { +} diff --git a/tests/ui/parser/macro/macro-keyword.stderr b/tests/ui/parser/macro/macro-keyword.stderr new file mode 100644 index 00000000000..bfe89e320e0 --- /dev/null +++ b/tests/ui/parser/macro/macro-keyword.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found reserved keyword `macro` + --> $DIR/macro-keyword.rs:1:4 + | +LL | fn macro() { + | ^^^^^ expected identifier, found reserved keyword + | +help: escape `macro` to use it as an identifier + | +LL | fn r#macro() { + | ++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/macro-mismatched-delim-brace-paren.rs b/tests/ui/parser/macro/macro-mismatched-delim-brace-paren.rs new file mode 100644 index 00000000000..404aa7b806a --- /dev/null +++ b/tests/ui/parser/macro/macro-mismatched-delim-brace-paren.rs @@ -0,0 +1,7 @@ +macro_rules! foo { ($($tt:tt)*) => () } + +fn main() { + foo! { + bar, "baz", 1, 2.0 + ) //~ ERROR mismatched closing delimiter +} diff --git a/tests/ui/parser/macro/macro-mismatched-delim-brace-paren.stderr b/tests/ui/parser/macro/macro-mismatched-delim-brace-paren.stderr new file mode 100644 index 00000000000..f9a3072229f --- /dev/null +++ b/tests/ui/parser/macro/macro-mismatched-delim-brace-paren.stderr @@ -0,0 +1,11 @@ +error: mismatched closing delimiter: `)` + --> $DIR/macro-mismatched-delim-brace-paren.rs:4:10 + | +LL | foo! { + | ^ unclosed delimiter +LL | bar, "baz", 1, 2.0 +LL | ) + | ^ mismatched closing delimiter + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/macro-mismatched-delim-paren-brace.rs b/tests/ui/parser/macro/macro-mismatched-delim-paren-brace.rs new file mode 100644 index 00000000000..1a1b9edfbcb --- /dev/null +++ b/tests/ui/parser/macro/macro-mismatched-delim-paren-brace.rs @@ -0,0 +1,5 @@ +fn main() { + foo! ( + bar, "baz", 1, 2.0 + } //~ ERROR mismatched closing delimiter +} //~ ERROR unexpected closing delimiter: `}` diff --git a/tests/ui/parser/macro/macro-mismatched-delim-paren-brace.stderr b/tests/ui/parser/macro/macro-mismatched-delim-paren-brace.stderr new file mode 100644 index 00000000000..34217e21ae9 --- /dev/null +++ b/tests/ui/parser/macro/macro-mismatched-delim-paren-brace.stderr @@ -0,0 +1,22 @@ +error: mismatched closing delimiter: `}` + --> $DIR/macro-mismatched-delim-paren-brace.rs:2:10 + | +LL | foo! ( + | ^ unclosed delimiter +LL | bar, "baz", 1, 2.0 +LL | } + | ^ mismatched closing delimiter + +error: unexpected closing delimiter: `}` + --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1 + | +LL | fn main() { + | - this delimiter might not be properly closed... +... +LL | } + | - ...as it matches this but it has different indentation +LL | } + | ^ unexpected closing delimiter + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/macro/macros-no-semicolon-items.rs b/tests/ui/parser/macro/macros-no-semicolon-items.rs new file mode 100644 index 00000000000..86889279cea --- /dev/null +++ b/tests/ui/parser/macro/macros-no-semicolon-items.rs @@ -0,0 +1,15 @@ +macro_rules! foo() //~ ERROR semicolon + //~| ERROR macros must contain at least one rule + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( //~ ERROR semicolon + blah + blah + blah +) + +fn main() { +} diff --git a/tests/ui/parser/macro/macros-no-semicolon-items.stderr b/tests/ui/parser/macro/macros-no-semicolon-items.stderr new file mode 100644 index 00000000000..f8f3ed83688 --- /dev/null +++ b/tests/ui/parser/macro/macros-no-semicolon-items.stderr @@ -0,0 +1,48 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:1:17 + | +LL | macro_rules! foo() + | ^^ + | +help: change the delimiters to curly braces + | +LL - macro_rules! foo() +LL + macro_rules! foo{} + | +help: add a semicolon + | +LL | macro_rules! foo(); + | + + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:8:5 + | +LL | bar!( + | _____^ +LL | | blah +LL | | blah +LL | | blah +LL | | ) + | |_^ + | +help: change the delimiters to curly braces + | +LL ~ bar!{ +LL | blah +LL | blah +LL | blah +LL + } + | +help: add a semicolon + | +LL | ); + | + + +error: macros must contain at least one rule + --> $DIR/macros-no-semicolon-items.rs:1:1 + | +LL | macro_rules! foo() + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/parser/macro/macros-no-semicolon.rs b/tests/ui/parser/macro/macros-no-semicolon.rs new file mode 100644 index 00000000000..24d1ae9e623 --- /dev/null +++ b/tests/ui/parser/macro/macros-no-semicolon.rs @@ -0,0 +1,5 @@ +fn main() { + assert_eq!(1, 2) //~ ERROR: expected `;` + assert_eq!(3, 4) //~ ERROR: expected `;` + println!("hello"); +} diff --git a/tests/ui/parser/macro/macros-no-semicolon.stderr b/tests/ui/parser/macro/macros-no-semicolon.stderr new file mode 100644 index 00000000000..f310662dbb0 --- /dev/null +++ b/tests/ui/parser/macro/macros-no-semicolon.stderr @@ -0,0 +1,18 @@ +error: expected `;`, found `assert_eq` + --> $DIR/macros-no-semicolon.rs:2:21 + | +LL | assert_eq!(1, 2) + | ^ help: add `;` here +LL | assert_eq!(3, 4) + | --------- unexpected token + +error: expected `;`, found `println` + --> $DIR/macros-no-semicolon.rs:3:21 + | +LL | assert_eq!(3, 4) + | ^ help: add `;` here +LL | println!("hello"); + | ------- unexpected token + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/macro/mbe_missing_right_paren.rs b/tests/ui/parser/macro/mbe_missing_right_paren.rs new file mode 100644 index 00000000000..85191931664 --- /dev/null +++ b/tests/ui/parser/macro/mbe_missing_right_paren.rs @@ -0,0 +1,3 @@ +// ignore-tidy-trailing-newlines +//~v ERROR this file contains an unclosed delimiter +macro_rules! abc(ؼ \ No newline at end of file diff --git a/tests/ui/parser/macro/mbe_missing_right_paren.stderr b/tests/ui/parser/macro/mbe_missing_right_paren.stderr new file mode 100644 index 00000000000..d45a2e3ab52 --- /dev/null +++ b/tests/ui/parser/macro/mbe_missing_right_paren.stderr @@ -0,0 +1,10 @@ +error: this file contains an unclosed delimiter + --> $DIR/mbe_missing_right_paren.rs:3:19 + | +LL | macro_rules! abc(ؼ + | - ^ + | | + | unclosed delimiter + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/misspelled-macro-rules.fixed b/tests/ui/parser/macro/misspelled-macro-rules.fixed new file mode 100644 index 00000000000..7471a5641c2 --- /dev/null +++ b/tests/ui/parser/macro/misspelled-macro-rules.fixed @@ -0,0 +1,13 @@ +// Regression test for issue #91227. + +//@ run-rustfix + +#![allow(unused_macros)] + +macro_rules! thing { +//~^ ERROR: expected one of +//~| HELP: perhaps you meant to define a macro + () => {} +} + +fn main() {} diff --git a/tests/ui/parser/macro/misspelled-macro-rules.rs b/tests/ui/parser/macro/misspelled-macro-rules.rs new file mode 100644 index 00000000000..8f63f37d3d3 --- /dev/null +++ b/tests/ui/parser/macro/misspelled-macro-rules.rs @@ -0,0 +1,13 @@ +// Regression test for issue #91227. + +//@ run-rustfix + +#![allow(unused_macros)] + +marco_rules! thing { +//~^ ERROR: expected one of +//~| HELP: perhaps you meant to define a macro + () => {} +} + +fn main() {} diff --git a/tests/ui/parser/macro/misspelled-macro-rules.stderr b/tests/ui/parser/macro/misspelled-macro-rules.stderr new file mode 100644 index 00000000000..fc718d8556d --- /dev/null +++ b/tests/ui/parser/macro/misspelled-macro-rules.stderr @@ -0,0 +1,10 @@ +error: expected one of `(`, `[`, or `{`, found `thing` + --> $DIR/misspelled-macro-rules.rs:7:14 + | +LL | marco_rules! thing { + | ----------- ^^^^^ expected one of `(`, `[`, or `{` + | | + | help: perhaps you meant to define a macro: `macro_rules` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/pub-method-macro.rs b/tests/ui/parser/macro/pub-method-macro.rs new file mode 100644 index 00000000000..0183bdcf622 --- /dev/null +++ b/tests/ui/parser/macro/pub-method-macro.rs @@ -0,0 +1,23 @@ +// Issue #18317 + +mod bleh { + macro_rules! defn { + ($n:ident) => ( + fn $n (&self) -> i32 { + println!("{}", stringify!($n)); + 1 + } + ) + } + + #[derive(Copy, Clone)] + pub struct S; + + impl S { + pub defn!(f); //~ ERROR can't qualify macro invocation with `pub` + //~^ HELP remove the visibility + //~| HELP try adjusting the macro to put `pub` inside the invocation + } +} + +fn main() {} diff --git a/tests/ui/parser/macro/pub-method-macro.stderr b/tests/ui/parser/macro/pub-method-macro.stderr new file mode 100644 index 00000000000..2e2c30dc6ad --- /dev/null +++ b/tests/ui/parser/macro/pub-method-macro.stderr @@ -0,0 +1,15 @@ +error: can't qualify macro invocation with `pub` + --> $DIR/pub-method-macro.rs:17:9 + | +LL | pub defn!(f); + | ^^^ + | + = help: try adjusting the macro to put `pub` inside the invocation +help: remove the visibility + | +LL - pub defn!(f); +LL + defn!(f); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/semi-after-closure-in-macro.rs b/tests/ui/parser/macro/semi-after-closure-in-macro.rs new file mode 100644 index 00000000000..1eeb04b8833 --- /dev/null +++ b/tests/ui/parser/macro/semi-after-closure-in-macro.rs @@ -0,0 +1,14 @@ +//@ check-pass + +// Checks that the fix in #103222 doesn't also disqualify semicolons after +// closures within parentheses *in macros*, where they're totally allowed. + +macro_rules! m { + (($expr:expr ; )) => { + $expr + }; +} + +fn main() { + let x = m!(( ||() ; )); +} diff --git a/tests/ui/parser/macro/trailing-question-in-macro-type.rs b/tests/ui/parser/macro/trailing-question-in-macro-type.rs new file mode 100644 index 00000000000..e2a681ddd11 --- /dev/null +++ b/tests/ui/parser/macro/trailing-question-in-macro-type.rs @@ -0,0 +1,14 @@ +macro_rules! fn_expr { + ($return_type:ty : $body:expr) => { + (|| -> $return_type { $body })() + }; + ($body:expr) => { + (|| $body)() + }; +} + + +fn main() { + fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + //~^ ERROR cannot find value `o` in this scope +} diff --git a/tests/ui/parser/macro/trailing-question-in-macro-type.stderr b/tests/ui/parser/macro/trailing-question-in-macro-type.stderr new file mode 100644 index 00000000000..e3d33bf251d --- /dev/null +++ b/tests/ui/parser/macro/trailing-question-in-macro-type.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `o` in this scope + --> $DIR/trailing-question-in-macro-type.rs:12:15 + | +LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + | ^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/parser/macros-no-semicolon-items.rs b/tests/ui/parser/macros-no-semicolon-items.rs deleted file mode 100644 index 86889279cea..00000000000 --- a/tests/ui/parser/macros-no-semicolon-items.rs +++ /dev/null @@ -1,15 +0,0 @@ -macro_rules! foo() //~ ERROR semicolon - //~| ERROR macros must contain at least one rule - -macro_rules! bar { - ($($tokens:tt)*) => {} -} - -bar!( //~ ERROR semicolon - blah - blah - blah -) - -fn main() { -} diff --git a/tests/ui/parser/macros-no-semicolon-items.stderr b/tests/ui/parser/macros-no-semicolon-items.stderr deleted file mode 100644 index f8f3ed83688..00000000000 --- a/tests/ui/parser/macros-no-semicolon-items.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/macros-no-semicolon-items.rs:1:17 - | -LL | macro_rules! foo() - | ^^ - | -help: change the delimiters to curly braces - | -LL - macro_rules! foo() -LL + macro_rules! foo{} - | -help: add a semicolon - | -LL | macro_rules! foo(); - | + - -error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/macros-no-semicolon-items.rs:8:5 - | -LL | bar!( - | _____^ -LL | | blah -LL | | blah -LL | | blah -LL | | ) - | |_^ - | -help: change the delimiters to curly braces - | -LL ~ bar!{ -LL | blah -LL | blah -LL | blah -LL + } - | -help: add a semicolon - | -LL | ); - | + - -error: macros must contain at least one rule - --> $DIR/macros-no-semicolon-items.rs:1:1 - | -LL | macro_rules! foo() - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/parser/macros-no-semicolon.rs b/tests/ui/parser/macros-no-semicolon.rs deleted file mode 100644 index 24d1ae9e623..00000000000 --- a/tests/ui/parser/macros-no-semicolon.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - assert_eq!(1, 2) //~ ERROR: expected `;` - assert_eq!(3, 4) //~ ERROR: expected `;` - println!("hello"); -} diff --git a/tests/ui/parser/macros-no-semicolon.stderr b/tests/ui/parser/macros-no-semicolon.stderr deleted file mode 100644 index f310662dbb0..00000000000 --- a/tests/ui/parser/macros-no-semicolon.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: expected `;`, found `assert_eq` - --> $DIR/macros-no-semicolon.rs:2:21 - | -LL | assert_eq!(1, 2) - | ^ help: add `;` here -LL | assert_eq!(3, 4) - | --------- unexpected token - -error: expected `;`, found `println` - --> $DIR/macros-no-semicolon.rs:3:21 - | -LL | assert_eq!(3, 4) - | ^ help: add `;` here -LL | println!("hello"); - | ------- unexpected token - -error: aborting due to 2 previous errors - diff --git a/tests/ui/parser/mbe_missing_right_paren.rs b/tests/ui/parser/mbe_missing_right_paren.rs deleted file mode 100644 index 85191931664..00000000000 --- a/tests/ui/parser/mbe_missing_right_paren.rs +++ /dev/null @@ -1,3 +0,0 @@ -// ignore-tidy-trailing-newlines -//~v ERROR this file contains an unclosed delimiter -macro_rules! abc(ؼ \ No newline at end of file diff --git a/tests/ui/parser/mbe_missing_right_paren.stderr b/tests/ui/parser/mbe_missing_right_paren.stderr deleted file mode 100644 index d45a2e3ab52..00000000000 --- a/tests/ui/parser/mbe_missing_right_paren.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: this file contains an unclosed delimiter - --> $DIR/mbe_missing_right_paren.rs:3:19 - | -LL | macro_rules! abc(ؼ - | - ^ - | | - | unclosed delimiter - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/misspelled-macro-rules.fixed b/tests/ui/parser/misspelled-macro-rules.fixed deleted file mode 100644 index 7471a5641c2..00000000000 --- a/tests/ui/parser/misspelled-macro-rules.fixed +++ /dev/null @@ -1,13 +0,0 @@ -// Regression test for issue #91227. - -//@ run-rustfix - -#![allow(unused_macros)] - -macro_rules! thing { -//~^ ERROR: expected one of -//~| HELP: perhaps you meant to define a macro - () => {} -} - -fn main() {} diff --git a/tests/ui/parser/misspelled-macro-rules.rs b/tests/ui/parser/misspelled-macro-rules.rs deleted file mode 100644 index 8f63f37d3d3..00000000000 --- a/tests/ui/parser/misspelled-macro-rules.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Regression test for issue #91227. - -//@ run-rustfix - -#![allow(unused_macros)] - -marco_rules! thing { -//~^ ERROR: expected one of -//~| HELP: perhaps you meant to define a macro - () => {} -} - -fn main() {} diff --git a/tests/ui/parser/misspelled-macro-rules.stderr b/tests/ui/parser/misspelled-macro-rules.stderr deleted file mode 100644 index fc718d8556d..00000000000 --- a/tests/ui/parser/misspelled-macro-rules.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: expected one of `(`, `[`, or `{`, found `thing` - --> $DIR/misspelled-macro-rules.rs:7:14 - | -LL | marco_rules! thing { - | ----------- ^^^^^ expected one of `(`, `[`, or `{` - | | - | help: perhaps you meant to define a macro: `macro_rules` - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/pub-method-macro.rs b/tests/ui/parser/pub-method-macro.rs deleted file mode 100644 index 0183bdcf622..00000000000 --- a/tests/ui/parser/pub-method-macro.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Issue #18317 - -mod bleh { - macro_rules! defn { - ($n:ident) => ( - fn $n (&self) -> i32 { - println!("{}", stringify!($n)); - 1 - } - ) - } - - #[derive(Copy, Clone)] - pub struct S; - - impl S { - pub defn!(f); //~ ERROR can't qualify macro invocation with `pub` - //~^ HELP remove the visibility - //~| HELP try adjusting the macro to put `pub` inside the invocation - } -} - -fn main() {} diff --git a/tests/ui/parser/pub-method-macro.stderr b/tests/ui/parser/pub-method-macro.stderr deleted file mode 100644 index 2e2c30dc6ad..00000000000 --- a/tests/ui/parser/pub-method-macro.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: can't qualify macro invocation with `pub` - --> $DIR/pub-method-macro.rs:17:9 - | -LL | pub defn!(f); - | ^^^ - | - = help: try adjusting the macro to put `pub` inside the invocation -help: remove the visibility - | -LL - pub defn!(f); -LL + defn!(f); - | - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/semi-after-closure-in-macro.rs b/tests/ui/parser/semi-after-closure-in-macro.rs deleted file mode 100644 index 1eeb04b8833..00000000000 --- a/tests/ui/parser/semi-after-closure-in-macro.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ check-pass - -// Checks that the fix in #103222 doesn't also disqualify semicolons after -// closures within parentheses *in macros*, where they're totally allowed. - -macro_rules! m { - (($expr:expr ; )) => { - $expr - }; -} - -fn main() { - let x = m!(( ||() ; )); -} diff --git a/tests/ui/parser/trailing-question-in-macro-type.rs b/tests/ui/parser/trailing-question-in-macro-type.rs deleted file mode 100644 index e2a681ddd11..00000000000 --- a/tests/ui/parser/trailing-question-in-macro-type.rs +++ /dev/null @@ -1,14 +0,0 @@ -macro_rules! fn_expr { - ($return_type:ty : $body:expr) => { - (|| -> $return_type { $body })() - }; - ($body:expr) => { - (|| $body)() - }; -} - - -fn main() { - fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; - //~^ ERROR cannot find value `o` in this scope -} diff --git a/tests/ui/parser/trailing-question-in-macro-type.stderr b/tests/ui/parser/trailing-question-in-macro-type.stderr deleted file mode 100644 index e3d33bf251d..00000000000 --- a/tests/ui/parser/trailing-question-in-macro-type.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0425]: cannot find value `o` in this scope - --> $DIR/trailing-question-in-macro-type.rs:12:15 - | -LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; - | ^ not found in this scope - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0425`. -- cgit 1.4.1-3-g733a5 From e99f9c5ffcf5e412a13c974255031e33ab26015a Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 5 Jul 2025 20:21:51 -0700 Subject: rustc_builtin_macros: Make sure registered attributes stay sorted As with the list of builtin macros, use tidy to make sure the list of builtin attributes stays sorted. --- compiler/rustc_builtin_macros/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 0594f7e86c3..6bf590df5c9 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -108,6 +108,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { } register_attr! { + // tidy-alphabetical-start alloc_error_handler: alloc_error_handler::expand, autodiff_forward: autodiff::expand_forward, autodiff_reverse: autodiff::expand_reverse, @@ -120,6 +121,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { global_allocator: global_allocator::expand, test: test::expand_test, test_case: test::expand_test_case, + // tidy-alphabetical-end } register_derive! { -- cgit 1.4.1-3-g733a5 From 131cffb6baca60f119c33f2599a0e6051b05c365 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 5 Jul 2025 16:57:24 -0700 Subject: Rename tests named with `mbe` to use `macro` instead Most macro tests use `macro` in the name, making it easy to find and run tests relevant to macros. However, a few use `mbe` instead. Rename those to say `macro`. --- ...cro-async-trait-bound-theoretical-regression.rs | 21 ++++++++++ ...async-trait-bound-theoretical-regression.stderr | 47 ++++++++++++++++++++++ ...mbe-async-trait-bound-theoretical-regression.rs | 21 ---------- ...async-trait-bound-theoretical-regression.stderr | 47 ---------------------- .../macro-bare-trait-object-maybe-trait-bound.rs | 16 ++++++++ .../macro/macro-dotdotdot-may-not-begin-a-type.rs | 11 +++++ tests/ui/parser/macro/macro-missing-right-paren.rs | 3 ++ .../parser/macro/macro-missing-right-paren.stderr | 10 +++++ .../mbe-bare-trait-object-maybe-trait-bound.rs | 16 -------- .../macro/mbe-dotdotdot-may-not-begin-a-type.rs | 11 ----- tests/ui/parser/macro/mbe_missing_right_paren.rs | 3 -- .../ui/parser/macro/mbe_missing_right_paren.stderr | 10 ----- .../macro-bare-trait-objects-const-trait-bounds.rs | 24 +++++++++++ ...ro-bare-trait-objects-const-trait-bounds.stderr | 22 ++++++++++ ...cro-const-trait-bound-theoretical-regression.rs | 21 ++++++++++ ...const-trait-bound-theoretical-regression.stderr | 45 +++++++++++++++++++++ .../ui/traits/const-traits/macro-dyn-const-2015.rs | 14 +++++++ .../mbe-bare-trait-objects-const-trait-bounds.rs | 24 ----------- ...be-bare-trait-objects-const-trait-bounds.stderr | 22 ---------- ...mbe-const-trait-bound-theoretical-regression.rs | 21 ---------- ...const-trait-bound-theoretical-regression.stderr | 45 --------------------- tests/ui/traits/const-traits/mbe-dyn-const-2015.rs | 14 ------- 22 files changed, 234 insertions(+), 234 deletions(-) create mode 100644 tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs create mode 100644 tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr delete mode 100644 tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs delete mode 100644 tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr create mode 100644 tests/ui/parser/macro/macro-bare-trait-object-maybe-trait-bound.rs create mode 100644 tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs create mode 100644 tests/ui/parser/macro/macro-missing-right-paren.rs create mode 100644 tests/ui/parser/macro/macro-missing-right-paren.stderr delete mode 100644 tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs delete mode 100644 tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs delete mode 100644 tests/ui/parser/macro/mbe_missing_right_paren.rs delete mode 100644 tests/ui/parser/macro/mbe_missing_right_paren.stderr create mode 100644 tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs create mode 100644 tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr create mode 100644 tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs create mode 100644 tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr create mode 100644 tests/ui/traits/const-traits/macro-dyn-const-2015.rs delete mode 100644 tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs delete mode 100644 tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.stderr delete mode 100644 tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs delete mode 100644 tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr delete mode 100644 tests/ui/traits/const-traits/mbe-dyn-const-2015.rs diff --git a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs new file mode 100644 index 00000000000..ea67831b68e --- /dev/null +++ b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs @@ -0,0 +1,21 @@ +// Demonstrates and records a theoretical regressions / breaking changes caused by the +// introduction of async trait bounds. + +// Setting the edition to 2018 since we don't regress `demo! { dyn async }` in Rust <2018. +//@ edition:2018 + +macro_rules! demo { + ($ty:ty) => { compile_error!("ty"); }; + //~^ ERROR ty + //~| ERROR ty + (impl $c:ident Trait) => {}; + (dyn $c:ident Trait) => {}; +} + +demo! { impl async Trait } +//~^ ERROR `async` trait bounds are unstable + +demo! { dyn async Trait } +//~^ ERROR `async` trait bounds are unstable + +fn main() {} diff --git a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr new file mode 100644 index 00000000000..6c3044e64d2 --- /dev/null +++ b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr @@ -0,0 +1,47 @@ +error: ty + --> $DIR/macro-async-trait-bound-theoretical-regression.rs:8:19 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | demo! { impl async Trait } + | -------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: ty + --> $DIR/macro-async-trait-bound-theoretical-regression.rs:8:19 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | demo! { dyn async Trait } + | ------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0658]: `async` trait bounds are unstable + --> $DIR/macro-async-trait-bound-theoretical-regression.rs:15:14 + | +LL | demo! { impl async Trait } + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: use the desugared name of the async trait, such as `AsyncFn` + +error[E0658]: `async` trait bounds are unstable + --> $DIR/macro-async-trait-bound-theoretical-regression.rs:18:13 + | +LL | demo! { dyn async Trait } + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: use the desugared name of the async trait, such as `AsyncFn` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs deleted file mode 100644 index ea67831b68e..00000000000 --- a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Demonstrates and records a theoretical regressions / breaking changes caused by the -// introduction of async trait bounds. - -// Setting the edition to 2018 since we don't regress `demo! { dyn async }` in Rust <2018. -//@ edition:2018 - -macro_rules! demo { - ($ty:ty) => { compile_error!("ty"); }; - //~^ ERROR ty - //~| ERROR ty - (impl $c:ident Trait) => {}; - (dyn $c:ident Trait) => {}; -} - -demo! { impl async Trait } -//~^ ERROR `async` trait bounds are unstable - -demo! { dyn async Trait } -//~^ ERROR `async` trait bounds are unstable - -fn main() {} diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr deleted file mode 100644 index a463944d113..00000000000 --- a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error: ty - --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:8:19 - | -LL | ($ty:ty) => { compile_error!("ty"); }; - | ^^^^^^^^^^^^^^^^^^^^ -... -LL | demo! { impl async Trait } - | -------------------------- in this macro invocation - | - = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: ty - --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:8:19 - | -LL | ($ty:ty) => { compile_error!("ty"); }; - | ^^^^^^^^^^^^^^^^^^^^ -... -LL | demo! { dyn async Trait } - | ------------------------- in this macro invocation - | - = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0658]: `async` trait bounds are unstable - --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14 - | -LL | demo! { impl async Trait } - | ^^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use the desugared name of the async trait, such as `AsyncFn` - -error[E0658]: `async` trait bounds are unstable - --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13 - | -LL | demo! { dyn async Trait } - | ^^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use the desugared name of the async trait, such as `AsyncFn` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/macro/macro-bare-trait-object-maybe-trait-bound.rs b/tests/ui/parser/macro/macro-bare-trait-object-maybe-trait-bound.rs new file mode 100644 index 00000000000..494e58c1ca5 --- /dev/null +++ b/tests/ui/parser/macro/macro-bare-trait-object-maybe-trait-bound.rs @@ -0,0 +1,16 @@ +// Check that `?Trait` matches the macro fragment specifier `ty`. +// Syntactically trait object types can be "bare" (i.e., lack the prefix `dyn`), +// even in newer editions like Rust 2021. +// Therefore the arm `?$Trait:path` shouldn't get reached. + +//@ edition: 2021 +//@ check-pass + +macro_rules! check { + ($Ty:ty) => {}; + (?$Trait:path) => { compile_error!("non-ty"); }; +} + +check! { ?Trait } + +fn main() {} diff --git a/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs b/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs new file mode 100644 index 00000000000..8be99f22d2e --- /dev/null +++ b/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs @@ -0,0 +1,11 @@ +// A bare `...` represents `CVarArgs` (`VaListImpl<'_>`) in function argument type +// position without being a proper type syntactically. +// This test ensures that we do not regress certain MBE calls would we ever promote +// `...` to a proper type syntactically. + +//@ check-pass + +macro_rules! ck { ($ty:ty) => { compile_error!(""); }; (...) => {}; } +ck!(...); + +fn main() {} diff --git a/tests/ui/parser/macro/macro-missing-right-paren.rs b/tests/ui/parser/macro/macro-missing-right-paren.rs new file mode 100644 index 00000000000..85191931664 --- /dev/null +++ b/tests/ui/parser/macro/macro-missing-right-paren.rs @@ -0,0 +1,3 @@ +// ignore-tidy-trailing-newlines +//~v ERROR this file contains an unclosed delimiter +macro_rules! abc(ؼ \ No newline at end of file diff --git a/tests/ui/parser/macro/macro-missing-right-paren.stderr b/tests/ui/parser/macro/macro-missing-right-paren.stderr new file mode 100644 index 00000000000..285f14830ce --- /dev/null +++ b/tests/ui/parser/macro/macro-missing-right-paren.stderr @@ -0,0 +1,10 @@ +error: this file contains an unclosed delimiter + --> $DIR/macro-missing-right-paren.rs:3:19 + | +LL | macro_rules! abc(ؼ + | - ^ + | | + | unclosed delimiter + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs b/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs deleted file mode 100644 index 494e58c1ca5..00000000000 --- a/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Check that `?Trait` matches the macro fragment specifier `ty`. -// Syntactically trait object types can be "bare" (i.e., lack the prefix `dyn`), -// even in newer editions like Rust 2021. -// Therefore the arm `?$Trait:path` shouldn't get reached. - -//@ edition: 2021 -//@ check-pass - -macro_rules! check { - ($Ty:ty) => {}; - (?$Trait:path) => { compile_error!("non-ty"); }; -} - -check! { ?Trait } - -fn main() {} diff --git a/tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs b/tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs deleted file mode 100644 index 8be99f22d2e..00000000000 --- a/tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs +++ /dev/null @@ -1,11 +0,0 @@ -// A bare `...` represents `CVarArgs` (`VaListImpl<'_>`) in function argument type -// position without being a proper type syntactically. -// This test ensures that we do not regress certain MBE calls would we ever promote -// `...` to a proper type syntactically. - -//@ check-pass - -macro_rules! ck { ($ty:ty) => { compile_error!(""); }; (...) => {}; } -ck!(...); - -fn main() {} diff --git a/tests/ui/parser/macro/mbe_missing_right_paren.rs b/tests/ui/parser/macro/mbe_missing_right_paren.rs deleted file mode 100644 index 85191931664..00000000000 --- a/tests/ui/parser/macro/mbe_missing_right_paren.rs +++ /dev/null @@ -1,3 +0,0 @@ -// ignore-tidy-trailing-newlines -//~v ERROR this file contains an unclosed delimiter -macro_rules! abc(ؼ \ No newline at end of file diff --git a/tests/ui/parser/macro/mbe_missing_right_paren.stderr b/tests/ui/parser/macro/mbe_missing_right_paren.stderr deleted file mode 100644 index d45a2e3ab52..00000000000 --- a/tests/ui/parser/macro/mbe_missing_right_paren.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: this file contains an unclosed delimiter - --> $DIR/mbe_missing_right_paren.rs:3:19 - | -LL | macro_rules! abc(ؼ - | - ^ - | | - | unclosed delimiter - -error: aborting due to 1 previous error - diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs new file mode 100644 index 00000000000..a5f6ae198f6 --- /dev/null +++ b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs @@ -0,0 +1,24 @@ +// Ensure that we don't consider `const Trait` to +// match the macro fragment specifier `ty` as that would be a breaking +// change theoretically speaking. Syntactically trait object types can +// be "bare", i.e., lack the prefix `dyn`. +// By contrast, `?Trait` *does* match `ty` and therefore an arm like +// `?$Trait:path` would never be reached. +// See `parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs`. +// `[const] Trait` is already an error for a `ty` fragment, +// so we do not need to prevent that. + +macro_rules! check { + ($Type:ty) => { + compile_error!("ty"); + }; + (const $Trait:path) => {}; + ([const] $Trait:path) => {}; +} + +check! { const Trait } +check! { [const] Trait } +//~^ ERROR: expected identifier, found `]` +//~| ERROR: const trait impls are experimental + +fn main() {} diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr new file mode 100644 index 00000000000..bc0e48112b9 --- /dev/null +++ b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr @@ -0,0 +1,22 @@ +error: expected identifier, found `]` + --> $DIR/macro-bare-trait-objects-const-trait-bounds.rs:20:16 + | +LL | ($Type:ty) => { + | -------- while parsing argument for this `ty` macro fragment +... +LL | check! { [const] Trait } + | ^ expected identifier + +error[E0658]: const trait impls are experimental + --> $DIR/macro-bare-trait-objects-const-trait-bounds.rs:20:11 + | +LL | check! { [const] Trait } + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs new file mode 100644 index 00000000000..3dcdb0cad94 --- /dev/null +++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs @@ -0,0 +1,21 @@ +// Demonstrates and records a theoretical regressions / breaking changes caused by the +// introduction of const trait bounds. + +// Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018. +//@ edition:2018 + +macro_rules! demo { + ($ty:ty) => { compile_error!("ty"); }; + //~^ ERROR ty + //~| ERROR ty + (impl $c:ident Trait) => {}; + (dyn $c:ident Trait) => {}; +} + +demo! { impl const Trait } +//~^ ERROR const trait impls are experimental + +demo! { dyn const Trait } +//~^ ERROR const trait impls are experimental + +fn main() {} diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr new file mode 100644 index 00000000000..5dd648554c9 --- /dev/null +++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr @@ -0,0 +1,45 @@ +error: ty + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:8:19 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | demo! { impl const Trait } + | -------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: ty + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:8:19 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | demo! { dyn const Trait } + | ------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0658]: const trait impls are experimental + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:15:14 + | +LL | demo! { impl const Trait } + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: const trait impls are experimental + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:18:13 + | +LL | demo! { dyn const Trait } + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/macro-dyn-const-2015.rs b/tests/ui/traits/const-traits/macro-dyn-const-2015.rs new file mode 100644 index 00000000000..fadfbe66788 --- /dev/null +++ b/tests/ui/traits/const-traits/macro-dyn-const-2015.rs @@ -0,0 +1,14 @@ +// Ensure that the introduction of const trait bound didn't regress this code in Rust 2015. +// See also `mbe-const-trait-bound-theoretical-regression.rs`. + +//@ edition: 2015 +//@ check-pass + +macro_rules! check { + ($ty:ty) => { compile_error!("ty"); }; + (dyn $c:ident) => {}; +} + +check! { dyn const } + +fn main() {} diff --git a/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs deleted file mode 100644 index a5f6ae198f6..00000000000 --- a/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Ensure that we don't consider `const Trait` to -// match the macro fragment specifier `ty` as that would be a breaking -// change theoretically speaking. Syntactically trait object types can -// be "bare", i.e., lack the prefix `dyn`. -// By contrast, `?Trait` *does* match `ty` and therefore an arm like -// `?$Trait:path` would never be reached. -// See `parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs`. -// `[const] Trait` is already an error for a `ty` fragment, -// so we do not need to prevent that. - -macro_rules! check { - ($Type:ty) => { - compile_error!("ty"); - }; - (const $Trait:path) => {}; - ([const] $Trait:path) => {}; -} - -check! { const Trait } -check! { [const] Trait } -//~^ ERROR: expected identifier, found `]` -//~| ERROR: const trait impls are experimental - -fn main() {} diff --git a/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.stderr b/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.stderr deleted file mode 100644 index 56dad5301a4..00000000000 --- a/tests/ui/traits/const-traits/mbe-bare-trait-objects-const-trait-bounds.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: expected identifier, found `]` - --> $DIR/mbe-bare-trait-objects-const-trait-bounds.rs:20:16 - | -LL | ($Type:ty) => { - | -------- while parsing argument for this `ty` macro fragment -... -LL | check! { [const] Trait } - | ^ expected identifier - -error[E0658]: const trait impls are experimental - --> $DIR/mbe-bare-trait-objects-const-trait-bounds.rs:20:11 - | -LL | check! { [const] Trait } - | ^^^^^ - | - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs deleted file mode 100644 index 3dcdb0cad94..00000000000 --- a/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Demonstrates and records a theoretical regressions / breaking changes caused by the -// introduction of const trait bounds. - -// Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018. -//@ edition:2018 - -macro_rules! demo { - ($ty:ty) => { compile_error!("ty"); }; - //~^ ERROR ty - //~| ERROR ty - (impl $c:ident Trait) => {}; - (dyn $c:ident Trait) => {}; -} - -demo! { impl const Trait } -//~^ ERROR const trait impls are experimental - -demo! { dyn const Trait } -//~^ ERROR const trait impls are experimental - -fn main() {} diff --git a/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr deleted file mode 100644 index f4b401b7386..00000000000 --- a/tests/ui/traits/const-traits/mbe-const-trait-bound-theoretical-regression.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error: ty - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19 - | -LL | ($ty:ty) => { compile_error!("ty"); }; - | ^^^^^^^^^^^^^^^^^^^^ -... -LL | demo! { impl const Trait } - | -------------------------- in this macro invocation - | - = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: ty - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19 - | -LL | ($ty:ty) => { compile_error!("ty"); }; - | ^^^^^^^^^^^^^^^^^^^^ -... -LL | demo! { dyn const Trait } - | ------------------------- in this macro invocation - | - = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0658]: const trait impls are experimental - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:15:14 - | -LL | demo! { impl const Trait } - | ^^^^^ - | - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: const trait impls are experimental - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:18:13 - | -LL | demo! { dyn const Trait } - | ^^^^^ - | - = note: see issue #67792 for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs b/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs deleted file mode 100644 index fadfbe66788..00000000000 --- a/tests/ui/traits/const-traits/mbe-dyn-const-2015.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Ensure that the introduction of const trait bound didn't regress this code in Rust 2015. -// See also `mbe-const-trait-bound-theoretical-regression.rs`. - -//@ edition: 2015 -//@ check-pass - -macro_rules! check { - ($ty:ty) => { compile_error!("ty"); }; - (dyn $c:ident) => {}; -} - -check! { dyn const } - -fn main() {} -- cgit 1.4.1-3-g733a5 From 3fa0ec91d8f3f14f9514d45d93e6fb7fdf1ad89e Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 4 Jul 2025 12:42:33 +0200 Subject: Rewrite empty attribute lint Signed-off-by: Jonathan Brouwer --- .../rustc_attr_data_structures/src/attributes.rs | 4 +- .../src/encode_cross_crate.rs | 2 +- compiler/rustc_attr_data_structures/src/lints.rs | 1 + compiler/rustc_attr_parsing/messages.ftl | 4 + .../src/attributes/codegen_attrs.rs | 4 + compiler/rustc_attr_parsing/src/attributes/repr.rs | 7 +- compiler/rustc_attr_parsing/src/context.rs | 10 ++ compiler/rustc_attr_parsing/src/lints.rs | 6 + .../rustc_attr_parsing/src/session_diagnostics.rs | 7 + .../src/deriving/generic/mod.rs | 2 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- compiler/rustc_hir_analysis/src/check/check.rs | 7 +- compiler/rustc_lint/src/nonstandard_style.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 7 +- compiler/rustc_passes/src/check_attr.rs | 96 +++++-------- src/librustdoc/clean/types.rs | 2 +- .../src/arbitrary_source_item_ordering.rs | 2 +- .../clippy_lints/src/attrs/repr_attributes.rs | 2 +- .../src/default_union_representation.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- tests/pretty/hir-lifetimes.pp | 2 +- tests/pretty/hir-pretty-attr.pp | 2 +- tests/ui/attributes/malformed-attrs.rs | 1 + tests/ui/attributes/malformed-attrs.stderr | 148 +++++++++++---------- tests/ui/empty/empty-attributes.stderr | 36 +++-- tests/ui/repr/repr-empty-packed.stderr | 23 ++-- tests/ui/unpretty/exhaustive.hir.stdout | 3 +- 27 files changed, 195 insertions(+), 191 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 6af15da7d08..ba62be676d4 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -67,8 +67,6 @@ pub enum ReprAttr { ReprSimd, ReprTransparent, ReprAlign(Align), - // this one is just so we can emit a lint for it - ReprEmpty, } pub use ReprAttr::*; @@ -304,7 +302,7 @@ pub enum AttributeKind { PubTransparent(Span), /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). - Repr(ThinVec<(ReprAttr, Span)>), + Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, /// Represents `#[rustc_layout_scalar_valid_range_end]`. RustcLayoutScalarValidRangeEnd(Box, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 8ebd38a6ba7..b109ebbf47b 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -41,7 +41,7 @@ impl AttributeKind { Optimize(..) => No, PassByValue(..) => Yes, PubTransparent(..) => Yes, - Repr(..) => No, + Repr { .. } => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, diff --git a/compiler/rustc_attr_data_structures/src/lints.rs b/compiler/rustc_attr_data_structures/src/lints.rs index e34c54c6d32..60ca4d43ce9 100644 --- a/compiler/rustc_attr_data_structures/src/lints.rs +++ b/compiler/rustc_attr_data_structures/src/lints.rs @@ -12,4 +12,5 @@ pub struct AttributeLint { pub enum AttributeLintKind { UnusedDuplicate { this: Span, other: Span, warning: bool }, IllFormedAttributeInput { suggestions: Vec }, + EmptyAttribute { first_span: Span }, } diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 9ad46a83f50..8a709ea5d20 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -6,6 +6,10 @@ attr_parsing_deprecated_item_suggestion = .help = add `#![feature(deprecated_suggestion)]` to the crate root .note = see #94785 for more details +attr_parsing_empty_attribute = + unused attribute + .suggestion = remove this attribute + attr_parsing_empty_confusables = expected at least one confusable name attr_parsing_expected_one_cfg_pattern = diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 13f560dff38..cb3956d46a0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -298,6 +298,10 @@ impl CombineAttributeParser for TargetFeatureParser { cx.expected_list(cx.attr_span); return features; }; + if list.is_empty() { + cx.warn_empty_attribute(cx.attr_span); + return features; + } for item in list.mixed() { let Some(name_value) = item.meta_item() else { cx.expected_name_value(item.span(), Some(sym::enable)); diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 1c070dc2685..6a45832ed7f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -23,7 +23,8 @@ pub(crate) struct ReprParser; impl CombineAttributeParser for ReprParser { type Item = (ReprAttr, Span); const PATH: &[Symbol] = &[sym::repr]; - const CONVERT: ConvertFn = |items, _| AttributeKind::Repr(items); + const CONVERT: ConvertFn = + |items, first_span| AttributeKind::Repr { reprs: items, first_span }; // FIXME(jdonszelmann): never used const TEMPLATE: AttributeTemplate = template!(List: "C | Rust | align(...) | packed(...) | | transparent"); @@ -40,8 +41,8 @@ impl CombineAttributeParser for ReprParser { }; if list.is_empty() { - // this is so validation can emit a lint - reprs.push((ReprAttr::ReprEmpty, cx.attr_span)); + cx.warn_empty_attribute(cx.attr_span); + return reprs; } for param in list.mixed() { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 2a01ee58493..bcd7b024a9e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -165,6 +165,7 @@ mod private { #[allow(private_interfaces)] pub trait Stage: Sized + 'static + Sealed { type Id: Copy; + const SHOULD_EMIT_LINTS: bool; fn parsers() -> &'static group_type!(Self); @@ -175,6 +176,7 @@ pub trait Stage: Sized + 'static + Sealed { #[allow(private_interfaces)] impl Stage for Early { type Id = NodeId; + const SHOULD_EMIT_LINTS: bool = false; fn parsers() -> &'static group_type!(Self) { &early::ATTRIBUTE_PARSERS @@ -188,6 +190,7 @@ impl Stage for Early { #[allow(private_interfaces)] impl Stage for Late { type Id = HirId; + const SHOULD_EMIT_LINTS: bool = true; fn parsers() -> &'static group_type!(Self) { &late::ATTRIBUTE_PARSERS @@ -228,6 +231,9 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { /// must be delayed until after HIR is built. This method will take care of the details of /// that. pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) { + if !S::SHOULD_EMIT_LINTS { + return; + } let id = self.target_id; (self.emit_lint)(AttributeLint { id, span, kind: lint }); } @@ -409,6 +415,10 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { }, }) } + + pub(crate) fn warn_empty_attribute(&mut self, span: Span) { + self.emit_lint(AttributeLintKind::EmptyAttribute { first_span: span }, span); + } } impl<'f, 'sess, S: Stage> Deref for AcceptContext<'f, 'sess, S> { diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs index fee22293b47..e648ca4fdf8 100644 --- a/compiler/rustc_attr_parsing/src/lints.rs +++ b/compiler/rustc_attr_parsing/src/lints.rs @@ -28,5 +28,11 @@ pub fn emit_attribute_lint(lint: &AttributeLint, lint_emi }, ); } + AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, + *id, + *first_span, + session_diagnostics::EmptyAttributeList { attr_span: *first_span }, + ), } } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 6145f1e1d3e..28f6786f37f 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -473,6 +473,13 @@ pub(crate) struct EmptyConfusables { pub span: Span, } +#[derive(LintDiagnostic)] +#[diag(attr_parsing_empty_attribute)] +pub(crate) struct EmptyAttributeList { + #[suggestion(code = "", applicability = "machine-applicable")] + pub attr_span: Span, +} + #[derive(Diagnostic)] #[diag(attr_parsing_invalid_alignment_value, code = E0589)] pub(crate) struct InvalidAlignmentValue { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index d201ca196d6..8135f3744f8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -485,7 +485,7 @@ impl<'a> TraitDef<'a> { Annotatable::Item(item) => { let is_packed = matches!( AttributeParser::parse_limited(cx.sess, &item.attrs, sym::repr, item.span, item.id), - Some(Attribute::Parsed(AttributeKind::Repr(r))) if r.iter().any(|(x, _)| matches!(x, ReprPacked(..))) + Some(Attribute::Parsed(AttributeKind::Repr { reprs, .. })) if reprs.iter().any(|(x, _)| matches!(x, ReprPacked(..))) ); let newitem = match &item.kind { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 2713ec07f97..be63bb8ac59 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -109,7 +109,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if let hir::Attribute::Parsed(p) = attr { match p { - AttributeKind::Repr(reprs) => { + AttributeKind::Repr { reprs, first_span: _ } => { codegen_fn_attrs.alignment = reprs .iter() .filter_map( diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f4fcb13b1a1..bd89d010a3c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1395,8 +1395,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { let repr = def.repr(); if repr.packed() { - if let Some(reprs) = - attrs::find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr(r) => r) + if let Some(reprs) = attrs::find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr { reprs, .. } => reprs) { for (r, _) in reprs { if let ReprPacked(pack) = r @@ -1619,10 +1618,10 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { if def.variants().is_empty() { attrs::find_attr!( tcx.get_all_attrs(def_id), - attrs::AttributeKind::Repr(rs) => { + attrs::AttributeKind::Repr { reprs, first_span } => { struct_span_code_err!( tcx.dcx(), - rs.first().unwrap().1, + reprs.first().map(|repr| repr.1).unwrap_or(*first_span), E0084, "unsupported representation for zero-variant enum" ) diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 97e627f2eb2..ad7686b3e5b 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -168,7 +168,7 @@ impl EarlyLintPass for NonCamelCaseTypes { fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { let has_repr_c = matches!( AttributeParser::parse_limited(cx.sess(), &it.attrs, sym::repr, it.span, it.id), - Some(Attribute::Parsed(AttributeKind::Repr(r))) if r.iter().any(|(r, _)| r == &ReprAttr::ReprC) + Some(Attribute::Parsed(AttributeKind::Repr { reprs, ..})) if reprs.iter().any(|(r, _)| r == &ReprAttr::ReprC) ); if has_repr_c { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f1b16ea54e6..b780b1c5776 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1525,7 +1525,8 @@ impl<'tcx> TyCtxt<'tcx> { field_shuffle_seed ^= user_seed; } - if let Some(reprs) = attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr(r) => r) + if let Some(reprs) = + attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr { reprs, .. } => reprs) { for (r, _) in reprs { flags.insert(match *r { @@ -1566,10 +1567,6 @@ impl<'tcx> TyCtxt<'tcx> { max_align = max_align.max(Some(align)); ReprFlags::empty() } - attr::ReprEmpty => { - /* skip these, they're just for diagnostics */ - ReprFlags::empty() - } }); } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 18b3ab12e2d..3fa5cdc36bc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -160,7 +160,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/ } - Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ + Attribute::Parsed(AttributeKind::Repr { .. }) => { /* handled below this loop and elsewhere */ } Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { self.check_object_lifetime_default(hir_id); @@ -1948,7 +1948,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // #[repr(foo)] // #[repr(bar, align(8))] // ``` - let reprs = find_attr!(attrs, AttributeKind::Repr(r) => r.as_slice()).unwrap_or(&[]); + let (reprs, first_attr_span) = find_attr!(attrs, AttributeKind::Repr { reprs, first_span } => (reprs.as_slice(), Some(*first_span))).unwrap_or((&[], None)); let mut int_reprs = 0; let mut is_explicit_rust = false; @@ -2045,31 +2045,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> { continue; } } - // FIXME(jdonszelmann): move the diagnostic for unused repr attrs here, I think - // it's a better place for it. - ReprAttr::ReprEmpty => { - // catch `repr()` with no arguments, applied to an item (i.e. not `#![repr()]`) - if item.is_some() { - match target { - Target::Struct | Target::Union | Target::Enum => continue, - Target::Fn | Target::Method(_) => { - self.dcx().emit_err(errors::ReprAlignShouldBeAlign { - span: *repr_span, - item: target.name(), - }); - } - _ => { - self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { - hint_span: *repr_span, - span, - }); - } - } - } + }; + } - return; + // catch `repr()` with no arguments, applied to an item (i.e. not `#![repr()]`) + if let Some(first_attr_span) = first_attr_span + && reprs.is_empty() + && item.is_some() + { + match target { + Target::Struct | Target::Union | Target::Enum => {} + Target::Fn | Target::Method(_) => { + self.dcx().emit_err(errors::ReprAlignShouldBeAlign { + span: first_attr_span, + item: target.name(), + }); } - }; + _ => { + self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { + hint_span: first_attr_span, + span, + }); + } + } + return; } // Just point at all repr hints if there are any incompatibilities. @@ -2324,43 +2323,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute, style: Option) { - // FIXME(jdonszelmann): deduplicate these checks after more attrs are parsed. This is very - // ugly now but can 100% be removed later. - if let Attribute::Parsed(p) = attr { - match p { - AttributeKind::Repr(reprs) => { - for (r, span) in reprs { - if let ReprAttr::ReprEmpty = r { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - *span, - errors::Unused { - attr_span: *span, - note: errors::UnusedNote::EmptyList { name: sym::repr }, - }, - ); - } - } - return; - } - AttributeKind::TargetFeature(features, span) if features.len() == 0 => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - *span, - errors::Unused { - attr_span: *span, - note: errors::UnusedNote::EmptyList { name: sym::target_feature }, - }, - ); - return; - } - _ => {} - }; - } - // Warn on useless empty attributes. + // FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute` let note = if attr.has_any_name(&[ sym::macro_use, sym::allow, @@ -2576,7 +2540,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) { - if !find_attr!(attrs, AttributeKind::Repr(r) => r.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) + if !find_attr!(attrs, AttributeKind::Repr { reprs, .. } => reprs.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) .unwrap_or(false) { self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span }); @@ -2852,8 +2816,12 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { ATTRS_TO_CHECK.iter().find(|attr_to_check| attr.has_name(**attr_to_check)) { (attr.span(), *a) - } else if let Attribute::Parsed(AttributeKind::Repr(r)) = attr { - (r.first().unwrap().1, sym::repr) + } else if let Attribute::Parsed(AttributeKind::Repr { + reprs: _, + first_span: first_attr_span, + }) = attr + { + (*first_attr_span, sym::repr) } else { continue; }; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index de920469fdc..a05aab22f1e 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -784,7 +784,7 @@ impl Item { // don't want it it `Item::attrs`. hir::Attribute::Parsed(AttributeKind::Deprecation { .. }) => None, // We have separate pretty-printing logic for `#[repr(..)]` attributes. - hir::Attribute::Parsed(AttributeKind::Repr(..)) => None, + hir::Attribute::Parsed(AttributeKind::Repr { .. }) => None, // target_feature is special-cased because cargo-semver-checks uses it hir::Attribute::Parsed(AttributeKind::TargetFeature(features, _)) => { let mut output = String::new(); diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index b9ae9afe851..8b6bfaebbe5 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -266,7 +266,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { .tcx .hir_attrs(item.hir_id()) .iter() - .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr(..)))) + .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr{ .. }))) { // Do not lint items with a `#[repr]` attribute as their layout may be imposed by an external API. return; diff --git a/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs index 05d8a8c26d1..3e8808cec61 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs @@ -9,7 +9,7 @@ use clippy_utils::msrvs::{self, Msrv}; use super::REPR_PACKED_WITHOUT_ABI; pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute], msrv: Msrv) { - if let Some(reprs) = find_attr!(attrs, AttributeKind::Repr(r) => r) { + if let Some(reprs) = find_attr!(attrs, AttributeKind::Repr { reprs, .. } => reprs) { let packed_span = reprs .iter() .find(|(r, _)| matches!(r, ReprAttr::ReprPacked(..))) diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index 615421f3a40..9bf2144e445 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -99,5 +99,5 @@ fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsR fn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { let attrs = cx.tcx.hir_attrs(hir_id); - find_attr!(attrs, AttributeKind::Repr(r) if r.iter().any(|(x, _)| *x == ReprAttr::ReprC)) + find_attr!(attrs, AttributeKind::Repr { reprs, .. } if reprs.iter().any(|(x, _)| *x == ReprAttr::ReprC)) } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index a8b33418c8c..c01f0ffaac9 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1761,7 +1761,7 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - find_attr!(cx.tcx.hir_attrs(hir_id), AttributeKind::Repr(..)) + find_attr!(cx.tcx.hir_attrs(hir_id), AttributeKind::Repr { .. }) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { diff --git a/tests/pretty/hir-lifetimes.pp b/tests/pretty/hir-lifetimes.pp index 4d1ab9d383b..58de6d81915 100644 --- a/tests/pretty/hir-lifetimes.pp +++ b/tests/pretty/hir-lifetimes.pp @@ -69,7 +69,7 @@ type Q<'a> = dyn MyTrait<'a, 'a> + 'a; fn h<'b, F>(f: F, y: Foo<'b>) where F: for<'d> MyTrait<'d, 'b> { } // FIXME(?): attr printing is weird -#[attr = Repr([ReprC])] +#[attr = Repr {reprs: [ReprC]}] struct S<'a>(&'a u32); extern "C" { diff --git a/tests/pretty/hir-pretty-attr.pp b/tests/pretty/hir-pretty-attr.pp index d8cc8c424ca..db7489c1264 100644 --- a/tests/pretty/hir-pretty-attr.pp +++ b/tests/pretty/hir-pretty-attr.pp @@ -6,6 +6,6 @@ extern crate std; //@ pretty-mode:hir //@ pp-exact:hir-pretty-attr.pp -#[attr = Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])] +#[attr = Repr {reprs: [ReprC, ReprPacked(Align(4 bytes)), ReprTransparent]}] struct Example { } diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index a09fe86557d..aa52de63a60 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -47,6 +47,7 @@ //~^ ERROR malformed #[repr] //~^ ERROR malformed +//~| ERROR is not supported on function items #[rustc_as_ptr = 5] //~^ ERROR malformed #[inline = 5] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 9fe4f45b3ef..2f7bf50ead5 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,11 +1,11 @@ error: `cfg` is not followed by parentheses - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:102:1 | LL | #[cfg] | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)` error: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:103:1 + --> $DIR/malformed-attrs.rs:104:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)] | ++++++++++++++++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:210:1 + --> $DIR/malformed-attrs.rs:211:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -35,19 +35,19 @@ LL | #![windows_subsystem] | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![windows_subsystem = "windows|console"]` error: malformed `crate_name` attribute input - --> $DIR/malformed-attrs.rs:73:1 + --> $DIR/malformed-attrs.rs:74:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:80:1 + --> $DIR/malformed-attrs.rs:81:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` error: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:89:1 + --> $DIR/malformed-attrs.rs:90:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -60,49 +60,49 @@ LL | #[coverage(on)] | ++++ error: malformed `no_sanitize` attribute input - --> $DIR/malformed-attrs.rs:91:1 + --> $DIR/malformed-attrs.rs:92:1 | LL | #[no_sanitize] | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` error: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:99:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:106:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` error: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:107:1 + --> $DIR/malformed-attrs.rs:108:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:110:5 + --> $DIR/malformed-attrs.rs:111:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` error: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:115:1 + --> $DIR/malformed-attrs.rs:116:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` error: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:123:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:131:1 + --> $DIR/malformed-attrs.rs:132:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^^^^ @@ -117,109 +117,109 @@ LL + #[must_not_suspend] | error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:133:1 + --> $DIR/malformed-attrs.rs:134:1 | LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:142:5 + --> $DIR/malformed-attrs.rs:143:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:154:1 + --> $DIR/malformed-attrs.rs:155:1 | LL | #[marker = 3] | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:156:1 + --> $DIR/malformed-attrs.rs:157:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` error: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:164:5 + --> $DIR/malformed-attrs.rs:165:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` error: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:166:5 + --> $DIR/malformed-attrs.rs:167:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` error: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:170:5 + --> $DIR/malformed-attrs.rs:171:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` error: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:172:5 + --> $DIR/malformed-attrs.rs:173:5 | LL | #[linkage] | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:177:1 + --> $DIR/malformed-attrs.rs:178:1 | LL | #[allow] | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:179:1 + --> $DIR/malformed-attrs.rs:180:1 | LL | #[expect] | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:181:1 + --> $DIR/malformed-attrs.rs:182:1 | LL | #[warn] | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:184:1 | LL | #[deny] | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:186:1 | LL | #[forbid] | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:188:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` error: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:191:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:202:1 + --> $DIR/malformed-attrs.rs:203:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:206:1 + --> $DIR/malformed-attrs.rs:207:1 | LL | #[no_link()] | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` error: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:208:1 + --> $DIR/malformed-attrs.rs:209:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ @@ -234,7 +234,7 @@ LL + #[macro_use] | error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:214:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^^^^^^ @@ -249,31 +249,31 @@ LL + #[macro_export] | error: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:216:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:99:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:115:1 + --> $DIR/malformed-attrs.rs:116:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:123:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:216:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -292,7 +292,7 @@ LL | #[doc] = note: `#[deny(ill_formed_attribute_input)]` on by default error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:75:1 + --> $DIR/malformed-attrs.rs:76:1 | LL | #[doc] | ^^^^^^ @@ -301,7 +301,7 @@ LL | #[doc] = note: for more information, see issue #57571 error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:83:1 | LL | #[link] | ^^^^^^^ @@ -310,7 +310,7 @@ LL | #[link] = note: for more information, see issue #57571 error: invalid argument - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:188:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -382,7 +382,7 @@ LL | #[repr] | help: must be of the form: `#[repr(C | Rust | align(...) | packed(...) | | transparent)]` error[E0565]: malformed `rustc_as_ptr` attribute input - --> $DIR/malformed-attrs.rs:50:1 + --> $DIR/malformed-attrs.rs:51:1 | LL | #[rustc_as_ptr = 5] | ^^^^^^^^^^^^^^^---^ @@ -391,7 +391,7 @@ LL | #[rustc_as_ptr = 5] | help: must be of the form: `#[rustc_as_ptr]` error[E0539]: malformed `align` attribute input - --> $DIR/malformed-attrs.rs:55:1 + --> $DIR/malformed-attrs.rs:56:1 | LL | #[align] | ^^^^^^^^ @@ -400,7 +400,7 @@ LL | #[align] | help: must be of the form: `#[align()]` error[E0539]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:57:1 + --> $DIR/malformed-attrs.rs:58:1 | LL | #[optimize] | ^^^^^^^^^^^ @@ -409,7 +409,7 @@ LL | #[optimize] | help: must be of the form: `#[optimize(size|speed|none)]` error[E0565]: malformed `cold` attribute input - --> $DIR/malformed-attrs.rs:59:1 + --> $DIR/malformed-attrs.rs:60:1 | LL | #[cold = 1] | ^^^^^^^---^ @@ -418,13 +418,13 @@ LL | #[cold = 1] | help: must be of the form: `#[cold]` error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` - --> $DIR/malformed-attrs.rs:61:1 + --> $DIR/malformed-attrs.rs:62:1 | LL | #[must_use()] | ^^^^^^^^^^^^^ error[E0565]: malformed `no_mangle` attribute input - --> $DIR/malformed-attrs.rs:63:1 + --> $DIR/malformed-attrs.rs:64:1 | LL | #[no_mangle = 1] | ^^^^^^^^^^^^---^ @@ -433,7 +433,7 @@ LL | #[no_mangle = 1] | help: must be of the form: `#[no_mangle]` error[E0565]: malformed `naked` attribute input - --> $DIR/malformed-attrs.rs:65:1 + --> $DIR/malformed-attrs.rs:66:1 | LL | #[unsafe(naked())] | ^^^^^^^^^^^^^^--^^ @@ -442,7 +442,7 @@ LL | #[unsafe(naked())] | help: must be of the form: `#[naked]` error[E0565]: malformed `track_caller` attribute input - --> $DIR/malformed-attrs.rs:67:1 + --> $DIR/malformed-attrs.rs:68:1 | LL | #[track_caller()] | ^^^^^^^^^^^^^^--^ @@ -451,13 +451,13 @@ LL | #[track_caller()] | help: must be of the form: `#[track_caller]` error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:69:1 + --> $DIR/malformed-attrs.rs:70:1 | LL | #[export_name()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error[E0805]: malformed `used` attribute input - --> $DIR/malformed-attrs.rs:71:1 + --> $DIR/malformed-attrs.rs:72:1 | LL | #[used()] | ^^^^^^--^ @@ -473,7 +473,7 @@ LL + #[used] | error[E0539]: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:78:1 + --> $DIR/malformed-attrs.rs:79:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ @@ -482,19 +482,19 @@ LL | #[target_feature] | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:85:1 + --> $DIR/malformed-attrs.rs:86:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:87:1 + --> $DIR/malformed-attrs.rs:88:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^----^ @@ -503,7 +503,7 @@ LL | #[no_implicit_prelude = 23] | help: must be of the form: `#[no_implicit_prelude]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:118:1 + --> $DIR/malformed-attrs.rs:119:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -520,7 +520,7 @@ LL + #[must_use] | error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:128:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -529,7 +529,7 @@ LL | #[rustc_layout_scalar_valid_range_start] | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:130:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -538,7 +538,7 @@ LL | #[rustc_layout_scalar_valid_range_end] | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:197:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -558,8 +558,20 @@ LL | | #[coroutine = 63] || {} LL | | } | |_- not a `const fn` +error: `#[repr(align(...))]` is not supported on function items + --> $DIR/malformed-attrs.rs:48:1 + | +LL | #[repr] + | ^^^^^^^ + | +help: use `#[align(...)]` instead + --> $DIR/malformed-attrs.rs:48:1 + | +LL | #[repr] + | ^^^^^^^ + warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:148:1 + --> $DIR/malformed-attrs.rs:149:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -567,7 +579,7 @@ LL | #[diagnostic::do_not_recommend()] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:137:1 + --> $DIR/malformed-attrs.rs:138:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -575,7 +587,7 @@ LL | #[diagnostic::on_unimplemented] = help: at least one of the `message`, `note` and `label` options are expected warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:139:1 + --> $DIR/malformed-attrs.rs:140:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -583,7 +595,7 @@ LL | #[diagnostic::on_unimplemented = 1] = help: only `message`, `note` and `label` are allowed as options error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` - --> $DIR/malformed-attrs.rs:52:1 + --> $DIR/malformed-attrs.rs:53:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ @@ -592,7 +604,7 @@ LL | #[inline = 5] = note: for more information, see issue #57571 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:93:1 + --> $DIR/malformed-attrs.rs:94:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -601,7 +613,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:222:1 + --> $DIR/malformed-attrs.rs:223:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -610,7 +622,7 @@ LL | #[ignore = 1] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:110:23 + --> $DIR/malformed-attrs.rs:111:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -618,9 +630,9 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:111:23: 111:25}` -error: aborting due to 74 previous errors; 3 warnings emitted +error: aborting due to 75 previous errors; 3 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/empty/empty-attributes.stderr b/tests/ui/empty/empty-attributes.stderr index e86dea10c70..f0be56ddc6a 100644 --- a/tests/ui/empty/empty-attributes.stderr +++ b/tests/ui/empty/empty-attributes.stderr @@ -1,32 +1,16 @@ error: unused attribute - --> $DIR/empty-attributes.rs:9:1 + --> $DIR/empty-attributes.rs:2:1 | -LL | #[repr()] - | ^^^^^^^^^ help: remove this attribute +LL | #![allow()] + | ^^^^^^^^^^^ help: remove this attribute | - = note: attribute `repr` with an empty list has no effect + = note: attribute `allow` with an empty list has no effect note: the lint level is defined here --> $DIR/empty-attributes.rs:1:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: unused attribute - --> $DIR/empty-attributes.rs:12:1 - | -LL | #[target_feature()] - | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | - = note: attribute `target_feature` with an empty list has no effect - -error: unused attribute - --> $DIR/empty-attributes.rs:2:1 - | -LL | #![allow()] - | ^^^^^^^^^^^ help: remove this attribute - | - = note: attribute `allow` with an empty list has no effect - error: unused attribute --> $DIR/empty-attributes.rs:3:1 | @@ -67,5 +51,17 @@ LL | #![feature()] | = note: attribute `feature` with an empty list has no effect +error: unused attribute + --> $DIR/empty-attributes.rs:9:1 + | +LL | #[repr()] + | ^^^^^^^^^ help: remove this attribute + +error: unused attribute + --> $DIR/empty-attributes.rs:12:1 + | +LL | #[target_feature()] + | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute + error: aborting due to 8 previous errors diff --git a/tests/ui/repr/repr-empty-packed.stderr b/tests/ui/repr/repr-empty-packed.stderr index c824c2998b4..6565b2e8c1d 100644 --- a/tests/ui/repr/repr-empty-packed.stderr +++ b/tests/ui/repr/repr-empty-packed.stderr @@ -1,27 +1,26 @@ +error[E0517]: attribute should be applied to a struct or union + --> $DIR/repr-empty-packed.rs:5:8 + | +LL | #[repr(packed)] + | ^^^^^^ +LL | / pub enum Foo { +LL | | Bar, +LL | | Baz(i32), +LL | | } + | |_- not a struct or union + error: unused attribute --> $DIR/repr-empty-packed.rs:4:1 | LL | #[repr()] | ^^^^^^^^^ help: remove this attribute | - = note: attribute `repr` with an empty list has no effect note: the lint level is defined here --> $DIR/repr-empty-packed.rs:2:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error[E0517]: attribute should be applied to a struct or union - --> $DIR/repr-empty-packed.rs:5:8 - | -LL | #[repr(packed)] - | ^^^^^^ -LL | / pub enum Foo { -LL | | Bar, -LL | | Baz(i32), -LL | | } - | |_- not a struct or union - error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 2b8f3b21396..0a983b41ef3 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -64,7 +64,8 @@ mod attributes { #[doc = "outer doc attribute"] #[doc = "macro"] #[allow()] - #[attr = Repr([ReprC])] + #[attr = Repr {reprs: + [ReprC]}] struct Struct; } -- cgit 1.4.1-3-g733a5 From 33f2cc7eda7a97e2870f9c60a229211a5f416b7a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 5 Jul 2025 22:21:28 +0200 Subject: Fix line break after ":" in unpretty attribute print Signed-off-by: Jonathan Brouwer --- compiler/rustc_macros/src/print_attribute.rs | 3 ++- tests/ui/unpretty/deprecated-attr.stdout | 12 +++++------- tests/ui/unpretty/exhaustive.hir.stdout | 3 +-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_macros/src/print_attribute.rs b/compiler/rustc_macros/src/print_attribute.rs index 42d94e72ee9..9023520c750 100644 --- a/compiler/rustc_macros/src/print_attribute.rs +++ b/compiler/rustc_macros/src/print_attribute.rs @@ -21,7 +21,8 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok __p.word_space(","); } __p.word(#string_name); - __p.word_space(":"); + __p.word(":"); + __p.nbsp(); __printed_anything = true; } #name.print_attribute(__p); diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout index a2b645d00d0..042c2f61bd4 100644 --- a/tests/ui/unpretty/deprecated-attr.stdout +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -9,12 +9,12 @@ extern crate std; #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] struct PlainDeprecated; -#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note: -"here's why this is deprecated"}}] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, +note: "here's why this is deprecated"}}] struct DirectNote; -#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note: -"here's why this is deprecated"}}] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, +note: "here's why this is deprecated"}}] struct ExplicitNote; #[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), @@ -28,8 +28,6 @@ struct FlippedOrder; fn f() { // Attribute is ignored here (with a warning), but still preserved in HIR - #[attr = Deprecation {deprecation: - Deprecation {since: - Unspecified}}] + #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] 0 } diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 0a983b41ef3..a559d51ed5d 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -64,8 +64,7 @@ mod attributes { #[doc = "outer doc attribute"] #[doc = "macro"] #[allow()] - #[attr = Repr {reprs: - [ReprC]}] + #[attr = Repr {reprs: [ReprC]}] struct Struct; } -- cgit 1.4.1-3-g733a5