Skip to content

Improve -Z crate-attr diagnostics #138336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ pub fn mk_doc_comment(
Attribute { kind: AttrKind::DocComment(comment_kind, data), id: g.mk_attr_id(), style, span }
}

pub fn mk_attr(
fn mk_attr(
g: &AttrIdGenerator,
style: AttrStyle,
unsafety: Safety,
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ builtin_macros_format_unused_args = multiple unused formatting arguments

builtin_macros_format_use_positional = consider using a positional formatting argument instead

builtin_macros_invalid_crate_attribute = invalid crate attribute

builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
.note = only one `#[default]` attribute is needed
.label = `#[default]` used here
Expand Down
57 changes: 25 additions & 32 deletions compiler/rustc_builtin_macros/src/cmdline_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
//! Attributes injected into the crate root from command line using `-Z crate-attr`.

use rustc_ast::attr::mk_attr;
use rustc_ast::{self as ast, AttrItem, AttrStyle, token};
use rustc_parse::parser::ForceCollect;
use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_ast::{self as ast};
use rustc_errors::Diag;
use rustc_parse::parser::attr::InnerAttrPolicy;
use rustc_parse::{parse_in, source_str_to_stream};
use rustc_session::parse::ParseSess;
use rustc_span::FileName;

use crate::errors;

pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
for raw_attr in attrs {
let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
psess,
FileName::cli_crate_attr_source_code(raw_attr),
raw_attr.clone(),
));

let start_span = parser.token.span;
let AttrItem { unsafety, path, args, tokens: _ } =
match parser.parse_attr_item(ForceCollect::No) {
Ok(ai) => ai,
Err(err) => {
let source = format!("#![{raw_attr}]");
let parse = || -> Result<ast::Attribute, Vec<Diag<'_>>> {
let tokens = source_str_to_stream(
psess,
FileName::cli_crate_attr_source_code(raw_attr),
source,
None,
)?;
parse_in(psess, tokens, "<crate attribute>", |p| {
p.parse_attribute(InnerAttrPolicy::Permitted)
})
.map_err(|e| vec![e])
};
let meta = match parse() {
Ok(meta) => meta,
Err(errs) => {
for err in errs {
err.emit();
continue;
}
};
let end_span = parser.token.span;
if parser.token != token::Eof {
psess.dcx().emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
continue;
}
continue;
}
};

krate.attrs.push(mk_attr(
&psess.attr_id_generator,
AttrStyle::Inner,
unsafety,
path,
args,
start_span.to(end_span),
));
krate.attrs.push(meta);
}
}
7 changes: 0 additions & 7 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,6 @@ pub(crate) struct ProcMacro {
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_invalid_crate_attribute)]
pub(crate) struct InvalidCrateAttr {
#[primary_span]
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_non_abi)]
pub(crate) struct NonABI {
Expand Down
16 changes: 8 additions & 8 deletions tests/ui/attributes/z-crate-attr/garbage.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
error: unknown start of token: `
--> <crate attribute>:1:1
--> <crate attribute>:1:4
|
LL | `%~@$#
| ^
LL | #![`%~@$#]
| ^
|
help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
|
LL - `%~@$#
LL + '%~@$#
LL - #![`%~@$#]
LL + #!['%~@$#]
|

error: expected identifier, found `%`
--> <crate attribute>:1:2
--> <crate attribute>:1:5
|
LL | `%~@$#
| ^ expected identifier
LL | #![`%~@$#]
| ^ expected identifier

error: aborting due to 2 previous errors

6 changes: 2 additions & 4 deletions tests/ui/attributes/z-crate-attr/injection.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//@ compile-flags: '-Zcrate-attr=feature(yeet_expr)]fn main(){}#[inline'

fn foo() {}

//~? ERROR unexpected closing delimiter: `]`
//~? ERROR unexpected token
fn foo() {} //~ ERROR `main` function not found
17 changes: 12 additions & 5 deletions tests/ui/attributes/z-crate-attr/injection.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
error: unexpected closing delimiter: `]`
--> <crate attribute>:1:19
error: unexpected token: keyword `fn`
--> <crate attribute>:1:23
|
LL | feature(yeet_expr)]fn main(){}#[inline
| ^ unexpected closing delimiter
LL | #![feature(yeet_expr)]fn main(){}#[inline]
| ^^ unexpected token after this

error: aborting due to 1 previous error
error[E0601]: `main` function not found in crate `injection`
--> $DIR/injection.rs:3:12
|
LL | fn foo() {}
| ^ consider adding a `main` function to `$DIR/injection.rs`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0601`.
3 changes: 3 additions & 0 deletions tests/ui/attributes/z-crate-attr/injection2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//@ compile-flags: -Zcrate-attr=feature(yeet_expr)]#![allow(warnings)
//~? ERROR unexpected token
fn foo() {} //~ ERROR `main` function not found
15 changes: 15 additions & 0 deletions tests/ui/attributes/z-crate-attr/injection2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: unexpected token: `#`
--> <crate attribute>:1:23
|
LL | #![feature(yeet_expr)]#![allow(warnings)]
| ^ unexpected token after this

error[E0601]: `main` function not found in crate `injection2`
--> $DIR/injection2.rs:3:12
|
LL | fn foo() {}
| ^ consider adding a `main` function to `$DIR/injection2.rs`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0601`.
6 changes: 3 additions & 3 deletions tests/ui/attributes/z-crate-attr/inner-attr.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: expected identifier, found `#`
--> <crate attribute>:1:1
--> <crate attribute>:1:4
|
LL | #![feature(foo)]
| ^ expected identifier
LL | #![#![feature(foo)]]
| ^ expected identifier

error: aborting due to 1 previous error

4 changes: 1 addition & 3 deletions tests/ui/attributes/z-crate-attr/multiple.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//@ compile-flags: -Zcrate-attr=feature(foo),feature(bar)

//~? ERROR expected `]`
fn main() {}

//~? ERROR invalid crate attribute
8 changes: 4 additions & 4 deletions tests/ui/attributes/z-crate-attr/multiple.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: invalid crate attribute
--> <crate attribute>:1:1
error: expected `]`, found `,`
--> <crate attribute>:1:16
|
LL | feature(foo),feature(bar)
| ^^^^^^^^^^^^^
LL | #![feature(foo),feature(bar)]
| ^ expected `]`

error: aborting due to 1 previous error

4 changes: 1 addition & 3 deletions tests/ui/attributes/z-crate-attr/unbalanced-paren.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// Show diagnostics for unbalanced parens.
//@ compile-flags: -Zcrate-attr=(

//~? ERROR mismatched closing delimiter
fn main() {}

//~? ERROR this file contains an unclosed delimiter
13 changes: 7 additions & 6 deletions tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
error: this file contains an unclosed delimiter
--> <crate attribute>:1:2
error: mismatched closing delimiter: `]`
--> <crate attribute>:1:4
|
LL | (
| -^
| |
| unclosed delimiter
LL | #![(]
| -^^ mismatched closing delimiter
| ||
| |unclosed delimiter
| closing delimiter possibly meant for this

error: aborting due to 1 previous error

Loading