diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index b294328b0bb17..b0045c359160d 100644 --- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs @@ -8,7 +8,7 @@ use rustc_session::parse::ParseSess; use rustc_span::FileName; pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { - for raw_attr in attrs { + let injected = attrs.iter().filter_map(|raw_attr| { let source = format!("#![{raw_attr}]"); let parse = || -> Result>> { let tokens = source_str_to_stream( @@ -22,16 +22,15 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { }) .map_err(|e| vec![e]) }; - let meta = match parse() { - Ok(meta) => meta, + match parse() { + Ok(meta) => Some(meta), Err(errs) => { for err in errs { err.emit(); } - continue; + None } - }; - - krate.attrs.push(meta); - } + } + }); + krate.attrs.splice(0..0, injected); } diff --git a/tests/ui/attributes/z-crate-attr/ordering-cli.rs b/tests/ui/attributes/z-crate-attr/ordering-cli.rs new file mode 100644 index 0000000000000..877a25939b9f3 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/ordering-cli.rs @@ -0,0 +1,6 @@ +// Multiple `-Zcrate-attr` flags apply in command-line order, so the later `deny` wins. +//@ compile-flags: -Zcrate-attr=warn(unused) -Zcrate-attr=deny(unused) + +fn foo() {} //~ ERROR function `foo` is never used + +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/ordering-cli.stderr b/tests/ui/attributes/z-crate-attr/ordering-cli.stderr new file mode 100644 index 0000000000000..84c47716e62fb --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/ordering-cli.stderr @@ -0,0 +1,15 @@ +error: function `foo` is never used + --> $DIR/ordering-cli.rs:4:4 + | +LL | fn foo() {} + | ^^^ + | +note: the lint level is defined here + --> :1:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(dead_code)]` implied by `#[deny(unused)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/z-crate-attr/ordering-source.rs b/tests/ui/attributes/z-crate-attr/ordering-source.rs new file mode 100644 index 0000000000000..914851d3bb055 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/ordering-source.rs @@ -0,0 +1,9 @@ +// RFC 3791: `-Zcrate-attr` applies before the crate's own attributes, so `warn` here wins. +//@ check-pass +//@ compile-flags: -Zcrate-attr=deny(unused) + +#![warn(unused)] + +fn foo() {} //~ WARN function `foo` is never used + +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/ordering-source.stderr b/tests/ui/attributes/z-crate-attr/ordering-source.stderr new file mode 100644 index 0000000000000..66cf78738bf7c --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/ordering-source.stderr @@ -0,0 +1,15 @@ +warning: function `foo` is never used + --> $DIR/ordering-source.rs:7:4 + | +LL | fn foo() {} + | ^^^ + | +note: the lint level is defined here + --> $DIR/ordering-source.rs:5:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` + +warning: 1 warning emitted +