@@ -8,14 +8,14 @@ use crate::errors::{
8
8
ComparisonOperatorsCannotBeChained , ComparisonOperatorsCannotBeChainedSugg ,
9
9
ConstGenericWithoutBraces , ConstGenericWithoutBracesSugg , DocCommentOnParamType ,
10
10
DoubleColonInBound , ExpectedIdentifier , ExpectedSemi , ExpectedSemiSugg ,
11
- GenericParamsWithoutAngleBrackets , GenericParamsWithoutAngleBracketsSugg , InInTypo ,
12
- IncorrectAwait , IncorrectSemicolon , IncorrectUseOfAwait , ParenthesesInForHead ,
13
- ParenthesesInForHeadSugg , PatternMethodParamWithoutBody , QuestionMarkInType ,
14
- QuestionMarkInTypeSugg , SelfParamNotFirst , StructLiteralBodyWithoutPath ,
15
- StructLiteralBodyWithoutPathSugg , StructLiteralNeedingParens , StructLiteralNeedingParensSugg ,
16
- SuggEscapeToUseAsIdentifier , SuggRemoveComma , UnexpectedConstInGenericParam ,
17
- UnexpectedConstParamDeclaration , UnexpectedConstParamDeclarationSugg , UnmatchedAngleBrackets ,
18
- UseEqInstead ,
11
+ GenericParamsWithoutAngleBrackets , GenericParamsWithoutAngleBracketsSugg ,
12
+ HelpIdentifierStartsWithNumber , InInTypo , IncorrectAwait , IncorrectSemicolon ,
13
+ IncorrectUseOfAwait , ParenthesesInForHead , ParenthesesInForHeadSugg ,
14
+ PatternMethodParamWithoutBody , QuestionMarkInType , QuestionMarkInTypeSugg , SelfParamNotFirst ,
15
+ StructLiteralBodyWithoutPath , StructLiteralBodyWithoutPathSugg , StructLiteralNeedingParens ,
16
+ StructLiteralNeedingParensSugg , SuggEscapeToUseAsIdentifier , SuggRemoveComma ,
17
+ UnexpectedConstInGenericParam , UnexpectedConstParamDeclaration ,
18
+ UnexpectedConstParamDeclarationSugg , UnmatchedAngleBrackets , UseEqInstead ,
19
19
} ;
20
20
21
21
use crate :: fluent_generated as fluent;
@@ -280,6 +280,7 @@ impl<'a> Parser<'a> {
280
280
TokenKind :: CloseDelim ( Delimiter :: Brace ) ,
281
281
TokenKind :: CloseDelim ( Delimiter :: Parenthesis ) ,
282
282
] ;
283
+
283
284
let suggest_raw = match self . token . ident ( ) {
284
285
Some ( ( ident, false ) )
285
286
if ident. is_raw_guess ( )
@@ -295,18 +296,19 @@ impl<'a> Parser<'a> {
295
296
_ => None ,
296
297
} ;
297
298
298
- let suggest_remove_comma =
299
- if self . token == token :: Comma && self . look_ahead ( 1 , |t| t. is_ident ( ) ) {
300
- Some ( SuggRemoveComma { span : self . token . span } )
301
- } else {
302
- None
303
- } ;
299
+ let suggest_remove_comma = ( self . token == token :: Comma
300
+ && self . look_ahead ( 1 , |t| t. is_ident ( ) ) )
301
+ . then_some ( SuggRemoveComma { span : self . token . span } ) ;
302
+
303
+ let help_cannot_start_number =
304
+ self . is_lit_bad_ident ( ) . then_some ( HelpIdentifierStartsWithNumber ) ;
304
305
305
306
let err = ExpectedIdentifier {
306
307
span : self . token . span ,
307
308
token : self . token . clone ( ) ,
308
309
suggest_raw,
309
310
suggest_remove_comma,
311
+ help_cannot_start_number,
310
312
} ;
311
313
let mut err = err. into_diagnostic ( & self . sess . span_diagnostic ) ;
312
314
@@ -365,6 +367,17 @@ impl<'a> Parser<'a> {
365
367
err
366
368
}
367
369
370
+ /// Checks if the current token is a integer or float literal and looks like
371
+ /// it could be a invalid identifier with digits at the start.
372
+ pub ( super ) fn is_lit_bad_ident ( & mut self ) -> bool {
373
+ matches ! ( self . token. uninterpolate( ) . kind, token:: Literal ( Lit { kind: token:: LitKind :: Integer | token:: LitKind :: Float , .. } )
374
+ // ensure that the integer literal is followed by a *invalid*
375
+ // suffix: this is how we know that it is a identifier with an
376
+ // invalid beginning.
377
+ if rustc_ast:: MetaItemLit :: from_token( & self . token) . is_none( )
378
+ )
379
+ }
380
+
368
381
pub ( super ) fn expected_one_of_not_found (
369
382
& mut self ,
370
383
edible : & [ TokenKind ] ,
0 commit comments