Suggest quoting unquoted idents in attrs

This commit is contained in:
sjwang05 2023-12-26 18:34:44 -08:00
parent 6029085a6f
commit aa8ecd0652
No known key found for this signature in database
GPG key ID: 8725BCA68FE25D6C
8 changed files with 107 additions and 6 deletions

View file

@ -407,6 +407,9 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator
parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}`
parse_invalid_meta_item_unquoted_ident = expected unsuffixed literal, found `{$token}`
.suggestion = surround the identifier with quotation marks to parse it as a string
parse_invalid_offset_of = offset_of expects dot-separated field and variant names
parse_invalid_unicode_escape = invalid unicode character escape

View file

@ -973,6 +973,25 @@ pub(crate) struct InvalidMetaItem {
pub token: Token,
}
#[derive(Diagnostic)]
#[diag(parse_invalid_meta_item_unquoted_ident)]
pub(crate) struct InvalidMetaItemUnquotedIdent {
#[primary_span]
pub span: Span,
pub token: Token,
#[subdiagnostic]
pub sugg: InvalidMetaItemSuggQuoteIdent,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct InvalidMetaItemSuggQuoteIdent {
#[suggestion_part(code = "\"")]
pub before: Span,
#[suggestion_part(code = "\"")]
pub after: Span,
}
#[derive(Subdiagnostic)]
#[suggestion(
parse_sugg_escape_identifier,

View file

@ -1,4 +1,7 @@
use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute};
use crate::errors::{
InvalidMetaItem, InvalidMetaItemSuggQuoteIdent, InvalidMetaItemUnquotedIdent,
SuffixedLiteralInAttribute,
};
use crate::fluent_generated as fluent;
use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
@ -417,9 +420,26 @@ fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
Err(err) => err.cancel(),
}
Err(self
.dcx()
.create_err(InvalidMetaItem { span: self.token.span, token: self.token.clone() }))
let token = self.token.clone();
// Check for unquoted idents in meta items, e.g.: #[cfg(key = foo)]
// `from_expansion()` ensures we don't suggest for cases such as
// `#[cfg(feature = $expr)]` in macros
if self.prev_token == token::Eq && !self.token.span.from_expansion() {
let before = self.token.span.shrink_to_lo();
while matches!(self.token.kind, token::Ident(..)) {
self.bump();
}
let after = self.prev_token.span.shrink_to_hi();
let sugg = InvalidMetaItemSuggQuoteIdent { before, after };
return Err(self.dcx().create_err(InvalidMetaItemUnquotedIdent {
span: token.span,
token,
sugg,
}));
}
Err(self.dcx().create_err(InvalidMetaItem { span: token.span, token }))
}
}

View file

@ -7,5 +7,5 @@ fn main() {
}
#[deprecated(note = test)]
//~^ ERROR expected unsuffixed literal or identifier, found `test`
//~^ ERROR expected unsuffixed literal, found `test`
fn foo() {}

View file

@ -1,8 +1,13 @@
error: expected unsuffixed literal or identifier, found `test`
error: expected unsuffixed literal, found `test`
--> $DIR/issue-66340-deprecated-attr-non-meta-grammar.rs:9:21
|
LL | #[deprecated(note = test)]
| ^^^^
|
help: surround the identifier with quotation marks to parse it as a string
|
LL | #[deprecated(note = "test")]
| + +
error: aborting due to 1 previous error

View file

@ -0,0 +1,15 @@
// compile-flags: -Zdeduplicate-diagnostics=yes
// run-rustfix
fn main() {
#[cfg(key="foo")]
//~^ ERROR expected unsuffixed literal, found `foo`
//~| HELP surround the identifier with quotation marks to parse it as a string
println!();
#[cfg(key="bar")]
println!();
#[cfg(key="foo bar baz")]
//~^ ERROR expected unsuffixed literal, found `foo`
//~| HELP surround the identifier with quotation marks to parse it as a string
println!();
}

View file

@ -0,0 +1,15 @@
// compile-flags: -Zdeduplicate-diagnostics=yes
// run-rustfix
fn main() {
#[cfg(key=foo)]
//~^ ERROR expected unsuffixed literal, found `foo`
//~| HELP surround the identifier with quotation marks to parse it as a string
println!();
#[cfg(key="bar")]
println!();
#[cfg(key=foo bar baz)]
//~^ ERROR expected unsuffixed literal, found `foo`
//~| HELP surround the identifier with quotation marks to parse it as a string
println!();
}

View file

@ -0,0 +1,24 @@
error: expected unsuffixed literal, found `foo`
--> $DIR/attr-unquoted-ident.rs:5:15
|
LL | #[cfg(key=foo)]
| ^^^
|
help: surround the identifier with quotation marks to parse it as a string
|
LL | #[cfg(key="foo")]
| + +
error: expected unsuffixed literal, found `foo`
--> $DIR/attr-unquoted-ident.rs:11:15
|
LL | #[cfg(key=foo bar baz)]
| ^^^
|
help: surround the identifier with quotation marks to parse it as a string
|
LL | #[cfg(key="foo bar baz")]
| + +
error: aborting due to 2 previous errors