diff options
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 41 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/stmt.rs | 12 |
4 files changed, 40 insertions, 34 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 1662db36d10..63e5bc50513 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -939,6 +939,7 @@ pub(crate) struct ExpectedIdentifier { pub token: Token, pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>, pub suggest_remove_comma: Option<SuggRemoveComma>, + pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>, } impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { @@ -975,10 +976,18 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { sugg.add_to_diagnostic(&mut diag); } + if let Some(help) = self.help_cannot_start_number { + help.add_to_diagnostic(&mut diag); + } + diag } } +#[derive(Subdiagnostic)] +#[help(parse_invalid_identifier_with_leading_number)] +pub(crate) struct HelpIdentifierStartsWithNumber; + pub(crate) struct ExpectedSemi { pub span: Span, pub token: Token, @@ -1208,14 +1217,6 @@ pub(crate) struct SelfParamNotFirst { } #[derive(Diagnostic)] -#[diag(parse_invalid_identifier_with_leading_number)] -pub(crate) struct InvalidIdentiferStartsWithNumber { - #[primary_span] - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(parse_const_generic_without_braces)] pub(crate) struct ConstGenericWithoutBraces { #[primary_span] diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 0a65c37ea7b..5b12bcc1822 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -8,14 +8,14 @@ use crate::errors::{ ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg, ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentOnParamType, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, - GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, InInTypo, - IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, ParenthesesInForHead, - ParenthesesInForHeadSugg, PatternMethodParamWithoutBody, QuestionMarkInType, - QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, - StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg, - SuggEscapeToUseAsIdentifier, SuggRemoveComma, UnexpectedConstInGenericParam, - UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, - UseEqInstead, + GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, + HelpIdentifierStartsWithNumber, InInTypo, IncorrectAwait, IncorrectSemicolon, + IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg, + PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, + StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, + StructLiteralNeedingParensSugg, SuggEscapeToUseAsIdentifier, SuggRemoveComma, + UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, + UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, }; use crate::fluent_generated as fluent; @@ -280,6 +280,7 @@ impl<'a> Parser<'a> { TokenKind::CloseDelim(Delimiter::Brace), TokenKind::CloseDelim(Delimiter::Parenthesis), ]; + let suggest_raw = match self.token.ident() { Some((ident, false)) if ident.is_raw_guess() @@ -295,18 +296,19 @@ impl<'a> Parser<'a> { _ => None, }; - let suggest_remove_comma = - if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) { - Some(SuggRemoveComma { span: self.token.span }) - } else { - None - }; + let suggest_remove_comma = (self.token == token::Comma + && self.look_ahead(1, |t| t.is_ident())) + .then_some(SuggRemoveComma { span: self.token.span }); + + let help_cannot_start_number = + self.is_lit_bad_ident().then_some(HelpIdentifierStartsWithNumber); let err = ExpectedIdentifier { span: self.token.span, token: self.token.clone(), suggest_raw, suggest_remove_comma, + help_cannot_start_number, }; let mut err = err.into_diagnostic(&self.sess.span_diagnostic); @@ -365,6 +367,17 @@ impl<'a> Parser<'a> { err } + /// Checks if the current token is a integer or float literal and looks like + /// it could be a invalid identifier with digits at the start. + pub(super) fn is_lit_bad_ident(&mut self) -> bool { + matches!(self.token.uninterpolate().kind, token::Literal(Lit { kind: token::LitKind::Integer | token::LitKind::Float, .. }) + // ensure that the integer literal is followed by a *invalid* + // suffix: this is how we know that it is a identifier with an + // invalid beginning. + if rustc_ast::MetaItemLit::from_token(&self.token).is_none() + ) + } + pub(super) fn expected_one_of_not_found( &mut self, edible: &[TokenKind], diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 8e920f1c421..fc9f1d1330a 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -348,6 +348,10 @@ impl<'a> Parser<'a> { lo = self.token.span; } + if self.is_lit_bad_ident() { + return Err(self.expected_ident_found()); + } + let pat = if self.check(&token::BinOp(token::And)) || self.token.kind == token::AndAnd { self.parse_pat_deref(expected)? } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 92a22ffc2b0..fbe5b88c49e 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -273,7 +273,6 @@ impl<'a> Parser<'a> { self.bump(); } - self.report_invalid_identifier_error()?; let (pat, colon) = self.parse_pat_before_ty(None, RecoverComma::Yes, PatternLocation::LetBinding)?; @@ -366,17 +365,6 @@ impl<'a> Parser<'a> { Ok(P(ast::Local { ty, pat, kind, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None })) } - /// report error for `let 1x = 123` - pub fn report_invalid_identifier_error(&mut self) -> PResult<'a, ()> { - if let token::Literal(lit) = self.token.uninterpolate().kind && - rustc_ast::MetaItemLit::from_token(&self.token).is_none() && - (lit.kind == token::LitKind::Integer || lit.kind == token::LitKind::Float) && - self.look_ahead(1, |t| matches!(t.kind, token::Eq) || matches!(t.kind, token::Colon ) ) { - return Err(self.sess.create_err(errors::InvalidIdentiferStartsWithNumber { span: self.token.span })); - } - Ok(()) - } - fn check_let_else_init_bool_expr(&self, init: &ast::Expr) { if let ast::ExprKind::Binary(op, ..) = init.kind { if op.node.lazy() { |
