refactor: refactor identifier parsing somewhat

This commit is contained in:
Ezra Shaw 2023-03-17 21:35:43 +13:00
parent 85123d2504
commit c9ddb73184
No known key found for this signature in database
GPG Key ID: 67ABF16FB0ECD870
5 changed files with 31 additions and 23 deletions

View File

@ -336,7 +336,7 @@ parse_expected_identifier_found_reserved_keyword = expected identifier, found re
parse_expected_identifier_found_doc_comment = expected identifier, found doc comment
parse_expected_identifier = expected identifier
parse_sugg_escape_to_use_as_identifier = escape `{$ident_name}` to use it as an identifier
parse_sugg_escape_identifier = escape `{$ident_name}` to use it as an identifier
parse_sugg_remove_comma = remove this comma

View File

@ -888,12 +888,12 @@ pub(crate) struct InvalidMetaItem {
#[derive(Subdiagnostic)]
#[suggestion(
parse_sugg_escape_to_use_as_identifier,
parse_sugg_escape_identifier,
style = "verbose",
applicability = "maybe-incorrect",
code = "r#"
)]
pub(crate) struct SuggEscapeToUseAsIdentifier {
pub(crate) struct SuggEscapeIdentifier {
#[primary_span]
pub span: Span,
pub ident_name: String,
@ -937,7 +937,7 @@ pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
pub(crate) struct ExpectedIdentifier {
pub span: Span,
pub token: Token,
pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
pub suggest_raw: Option<SuggEscapeIdentifier>,
pub suggest_remove_comma: Option<SuggRemoveComma>,
pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>,
}

View File

@ -6,14 +6,14 @@
use crate::errors::{
AmbiguousPlus, AttributeOnParamType, BadQPathStage2, BadTypePlus, BadTypePlusSub,
ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg,
ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentOnParamType,
DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything,
DocCommentOnParamType, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
HelpIdentifierStartsWithNumber, InInTypo, IncorrectAwait, IncorrectSemicolon,
IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
StructLiteralNeedingParensSugg, SuggEscapeToUseAsIdentifier, SuggRemoveComma,
StructLiteralNeedingParensSugg, SuggEscapeIdentifier, SuggRemoveComma,
UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
};
@ -268,7 +268,16 @@ pub(super) fn span_to_snippet(&self, span: Span) -> Result<String, SpanSnippetEr
self.sess.source_map().span_to_snippet(span)
}
/// Emits an error with suggestions if an identifier was expected but not found.
pub(super) fn expected_ident_found(&mut self) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
if let TokenKind::DocComment(..) = self.prev_token.kind {
return DocCommentDoesNotDocumentAnything {
span: self.prev_token.span,
missing_comma: None,
}
.into_diagnostic(&self.sess.span_diagnostic);
}
let valid_follow = &[
TokenKind::Eq,
TokenKind::Colon,
@ -286,7 +295,7 @@ pub(super) fn expected_ident_found(&mut self) -> DiagnosticBuilder<'a, ErrorGuar
if ident.is_raw_guess()
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
{
Some(SuggEscapeToUseAsIdentifier {
Some(SuggEscapeIdentifier {
span: ident.span.shrink_to_lo(),
// `Symbol::to_string()` is different from `Symbol::into_diagnostic_arg()`,
// which uses `Symbol::to_ident_string()` and "helpfully" adds an implicit `r#`

View File

@ -1744,7 +1744,7 @@ fn parse_name_and_ty(
/// Parses a field identifier. Specialized version of `parse_ident_common`
/// for better diagnostics and suggestions.
fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
let (ident, is_raw) = self.ident_or_err()?;
let (ident, is_raw) = self.ident_or_err(true)?;
if !is_raw && ident.is_reserved() {
let snapshot = self.create_snapshot_for_diagnostic();
let err = if self.check_fn_front_matter(false, Case::Sensitive) {

View File

@ -42,8 +42,7 @@
use tracing::debug;
use crate::errors::{
DocCommentDoesNotDocumentAnything, IncorrectVisibilityRestriction, MismatchedClosingDelimiter,
NonStringAbiLiteral,
IncorrectVisibilityRestriction, MismatchedClosingDelimiter, NonStringAbiLiteral,
};
bitflags::bitflags! {
@ -552,19 +551,8 @@ pub fn parse_ident(&mut self) -> PResult<'a, Ident> {
self.parse_ident_common(true)
}
fn ident_or_err(&mut self) -> PResult<'a, (Ident, /* is_raw */ bool)> {
self.token.ident().ok_or_else(|| match self.prev_token.kind {
TokenKind::DocComment(..) => DocCommentDoesNotDocumentAnything {
span: self.prev_token.span,
missing_comma: None,
}
.into_diagnostic(&self.sess.span_diagnostic),
_ => self.expected_ident_found(),
})
}
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
let (ident, is_raw) = self.ident_or_err()?;
let (ident, is_raw) = self.ident_or_err(recover)?;
if !is_raw && ident.is_reserved() {
let mut err = self.expected_ident_found();
if recover {
@ -577,6 +565,17 @@ fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
Ok(ident)
}
fn ident_or_err(&mut self, _recover: bool) -> PResult<'a, (Ident, /* is_raw */ bool)> {
let result = self.token.ident().ok_or_else(|| self.expected_ident_found());
let (ident, is_raw) = match result {
Ok(ident) => ident,
Err(err) => return Err(err),
};
Ok((ident, is_raw))
}
/// Checks if the next token is `tok`, and returns `true` if so.
///
/// This method will automatically add `tok` to `expected_tokens` if `tok` is not