Rollup merge of #138336 - jyn514:crate-attr-diagnostics, r=compiler-errors
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. r? diagnostics
This commit is contained in:
commit
2b6835bf54
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 }
|
Attribute { kind: AttrKind::DocComment(comment_kind, data), id: g.mk_attr_id(), style, span }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_attr(
|
fn mk_attr(
|
||||||
g: &AttrIdGenerator,
|
g: &AttrIdGenerator,
|
||||||
style: AttrStyle,
|
style: AttrStyle,
|
||||||
unsafety: Safety,
|
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_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
|
builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
|
||||||
.note = only one `#[default]` attribute is needed
|
.note = only one `#[default]` attribute is needed
|
||||||
.label = `#[default]` used here
|
.label = `#[default]` used here
|
||||||
|
|
|
@ -1,44 +1,37 @@
|
||||||
//! Attributes injected into the crate root from command line using `-Z crate-attr`.
|
//! 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};
|
||||||
use rustc_ast::{self as ast, AttrItem, AttrStyle, token};
|
use rustc_errors::Diag;
|
||||||
use rustc_parse::parser::ForceCollect;
|
use rustc_parse::parser::attr::InnerAttrPolicy;
|
||||||
use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
|
use rustc_parse::{parse_in, source_str_to_stream};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::FileName;
|
use rustc_span::FileName;
|
||||||
|
|
||||||
use crate::errors;
|
|
||||||
|
|
||||||
pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
|
pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
|
||||||
for raw_attr in attrs {
|
for raw_attr in attrs {
|
||||||
let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
|
let source = format!("#![{raw_attr}]");
|
||||||
psess,
|
let parse = || -> Result<ast::Attribute, Vec<Diag<'_>>> {
|
||||||
FileName::cli_crate_attr_source_code(raw_attr),
|
let tokens = source_str_to_stream(
|
||||||
raw_attr.clone(),
|
psess,
|
||||||
));
|
FileName::cli_crate_attr_source_code(raw_attr),
|
||||||
|
source,
|
||||||
let start_span = parser.token.span;
|
None,
|
||||||
let AttrItem { unsafety, path, args, tokens: _ } =
|
)?;
|
||||||
match parser.parse_attr_item(ForceCollect::No) {
|
parse_in(psess, tokens, "<crate attribute>", |p| {
|
||||||
Ok(ai) => ai,
|
p.parse_attribute(InnerAttrPolicy::Permitted)
|
||||||
Err(err) => {
|
})
|
||||||
|
.map_err(|e| vec![e])
|
||||||
|
};
|
||||||
|
let meta = match parse() {
|
||||||
|
Ok(meta) => meta,
|
||||||
|
Err(errs) => {
|
||||||
|
for err in errs {
|
||||||
err.emit();
|
err.emit();
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
};
|
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(
|
krate.attrs.push(meta);
|
||||||
&psess.attr_id_generator,
|
|
||||||
AttrStyle::Inner,
|
|
||||||
unsafety,
|
|
||||||
path,
|
|
||||||
args,
|
|
||||||
start_span.to(end_span),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,13 +109,6 @@ pub(crate) struct ProcMacro {
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(builtin_macros_invalid_crate_attribute)]
|
|
||||||
pub(crate) struct InvalidCrateAttr {
|
|
||||||
#[primary_span]
|
|
||||||
pub(crate) span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(builtin_macros_non_abi)]
|
#[diag(builtin_macros_non_abi)]
|
||||||
pub(crate) struct NonABI {
|
pub(crate) struct NonABI {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
error: unknown start of token: `
|
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
|
help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
|
||||||
|
|
|
|
||||||
LL - `%~@$#
|
LL - #![`%~@$#]
|
||||||
LL + '%~@$#
|
LL + #!['%~@$#]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: expected identifier, found `%`
|
error: expected identifier, found `%`
|
||||||
--> <crate attribute>:1:2
|
--> <crate attribute>:1:5
|
||||||
|
|
|
|
||||||
LL | `%~@$#
|
LL | #![`%~@$#]
|
||||||
| ^ expected identifier
|
| ^ expected identifier
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
//@ compile-flags: '-Zcrate-attr=feature(yeet_expr)]fn main(){}#[inline'
|
//@ compile-flags: '-Zcrate-attr=feature(yeet_expr)]fn main(){}#[inline'
|
||||||
|
//~? ERROR unexpected token
|
||||||
fn foo() {}
|
fn foo() {} //~ ERROR `main` function not found
|
||||||
|
|
||||||
//~? ERROR unexpected closing delimiter: `]`
|
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
error: unexpected closing delimiter: `]`
|
error: unexpected token: keyword `fn`
|
||||||
--> <crate attribute>:1:19
|
--> <crate attribute>:1:23
|
||||||
|
|
|
|
||||||
LL | feature(yeet_expr)]fn main(){}#[inline
|
LL | #![feature(yeet_expr)]fn main(){}#[inline]
|
||||||
| ^ unexpected closing delimiter
|
| ^^ 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,8 +1,8 @@
|
||||||
error: expected identifier, found `#`
|
error: expected identifier, found `#`
|
||||||
--> <crate attribute>:1:1
|
--> <crate attribute>:1:4
|
||||||
|
|
|
|
||||||
LL | #![feature(foo)]
|
LL | #![#![feature(foo)]]
|
||||||
| ^ expected identifier
|
| ^ expected identifier
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
//@ compile-flags: -Zcrate-attr=feature(foo),feature(bar)
|
//@ compile-flags: -Zcrate-attr=feature(foo),feature(bar)
|
||||||
|
//~? ERROR expected `]`
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
//~? ERROR invalid crate attribute
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: invalid crate attribute
|
error: expected `]`, found `,`
|
||||||
--> <crate attribute>:1:1
|
--> <crate attribute>:1:16
|
||||||
|
|
|
|
||||||
LL | feature(foo),feature(bar)
|
LL | #![feature(foo),feature(bar)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^ expected `]`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// Show diagnostics for unbalanced parens.
|
// Show diagnostics for unbalanced parens.
|
||||||
//@ compile-flags: -Zcrate-attr=(
|
//@ compile-flags: -Zcrate-attr=(
|
||||||
|
//~? ERROR mismatched closing delimiter
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
//~? ERROR this file contains an unclosed delimiter
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
error: this file contains an unclosed delimiter
|
error: mismatched closing delimiter: `]`
|
||||||
--> <crate attribute>:1:2
|
--> <crate attribute>:1:4
|
||||||
|
|
|
|
||||||
LL | (
|
LL | #![(]
|
||||||
| -^
|
| -^^ mismatched closing delimiter
|
||||||
| |
|
| ||
|
||||||
| unclosed delimiter
|
| |unclosed delimiter
|
||||||
|
| closing delimiter possibly meant for this
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue