Improve -Z crate-attr
diagnostics
- Show the `#![ ... ]` in the span (to make it clear that it should not be included in the CLI argument) - Show more detailed errors when the crate has valid token trees but invalid syntax. Previously, `crate-attr=feature(foo),feature(bar)` would just say "invalid crate attribute" and point at the comma. Now, it explicitly says that the comma was unexpected, which is useful when using `--error-format=short`. It also fixes the column to show the correct span. - Recover from parse errors. Previously we would abort immediately on syntax errors; now we go on to try and type-check the rest of the crate. The new diagnostic code also happens to be slightly shorter.
This commit is contained in:
parent
092a284ba0
commit
d50a8d5fb3
14 changed files with 82 additions and 78 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
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),
|
||||
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) => {
|
||||
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;
|
||||
}
|
||||
|
||||
krate.attrs.push(mk_attr(
|
||||
&psess.attr_id_generator,
|
||||
AttrStyle::Inner,
|
||||
unsafety,
|
||||
path,
|
||||
args,
|
||||
start_span.to(end_span),
|
||||
));
|
||||
krate.attrs.push(meta);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
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 | `%~@$#
|
||||
LL | #![`%~@$#]
|
||||
| ^ expected identifier
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
tests/ui/attributes/z-crate-attr/injection2.rs
Normal file
3
tests/ui/attributes/z-crate-attr/injection2.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
//@ compile-flags: -Zcrate-attr=feature(yeet_expr)]#![allow(warnings)
|
||||
//~? ERROR unexpected token
|
||||
fn foo() {} //~ ERROR `main` function not found
|
15
tests/ui/attributes/z-crate-attr/injection2.stderr
Normal file
15
tests/ui/attributes/z-crate-attr/injection2.stderr
Normal file
|
@ -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`.
|
|
@ -1,7 +1,7 @@
|
|||
error: expected identifier, found `#`
|
||||
--> <crate attribute>:1:1
|
||||
--> <crate attribute>:1:4
|
||||
|
|
||||
LL | #![feature(foo)]
|
||||
LL | #![#![feature(foo)]]
|
||||
| ^ expected identifier
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//@ compile-flags: -Zcrate-attr=feature(foo),feature(bar)
|
||||
|
||||
//~? ERROR expected `]`
|
||||
fn main() {}
|
||||
|
||||
//~? ERROR invalid crate attribute
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue