Skip to content

Commit 773c50f

Browse files
author
Josh Goldberg
committed
Better error message for invalid bigint literals ending with n
Helps with the cases of decimals and exponentials, though not with numbers incorrectly starting with `0`. Fixes #28887.
1 parent 71286e3 commit 773c50f

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,14 @@
10151015
"category": "Error",
10161016
"code": 1351
10171017
},
1018+
"A bigint literal cannot use exponential notation.": {
1019+
"category": "Error",
1020+
"code": 1352
1021+
},
1022+
"A bigint literal must be an integer.": {
1023+
"category": "Error",
1024+
"code": 1353
1025+
},
10181026

10191027
"Duplicate identifier '{0}'.": {
10201028
"category": "Error",

src/compiler/scanner.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ namespace ts {
976976
}
977977

978978
if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
979-
checkForIdentifierStartAfterNumericLiteral();
979+
checkForIdentifierStartAfterNumericLiteral(decimalFragment === undefined && !!(tokenFlags & TokenFlags.Scientific));
980980
return {
981981
type: SyntaxKind.NumericLiteral,
982982
value: "" + +result // if value is not an integer, it can be safely coerced to a number
@@ -990,14 +990,26 @@ namespace ts {
990990
}
991991
}
992992

993-
function checkForIdentifierStartAfterNumericLiteral() {
993+
function checkForIdentifierStartAfterNumericLiteral(isScientific?: boolean) {
994994
if (!isIdentifierStart(text.charCodeAt(pos), languageVersion)) {
995995
return;
996996
}
997997

998998
const identifierStart = pos;
999999
const { length } = scanIdentifierParts();
1000-
error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
1000+
1001+
if (length === 1 && text[identifierStart] === "n") {
1002+
if (isScientific) {
1003+
error(Diagnostics.A_bigint_literal_cannot_use_exponential_notation, identifierStart, length);
1004+
}
1005+
else {
1006+
error(Diagnostics.A_bigint_literal_must_be_an_integer, identifierStart, length);
1007+
}
1008+
}
1009+
else {
1010+
error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
1011+
}
1012+
10011013
pos = identifierStart;
10021014
}
10031015

tests/baselines/reference/parseBigInt.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
tests/cases/compiler/parseBigInt.ts(51,20): error TS2736: Operator '+' cannot be applied to type '123n'.
22
tests/cases/compiler/parseBigInt.ts(52,23): error TS2736: Operator '+' cannot be applied to type '291n'.
33
tests/cases/compiler/parseBigInt.ts(56,25): error TS1005: ',' expected.
4-
tests/cases/compiler/parseBigInt.ts(57,25): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
5-
tests/cases/compiler/parseBigInt.ts(58,22): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
6-
tests/cases/compiler/parseBigInt.ts(59,28): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
4+
tests/cases/compiler/parseBigInt.ts(57,25): error TS1352: A bigint literal cannot use exponential notation.
5+
tests/cases/compiler/parseBigInt.ts(58,22): error TS1353: A bigint literal must be an integer.
6+
tests/cases/compiler/parseBigInt.ts(59,28): error TS1353: A bigint literal must be an integer.
77
tests/cases/compiler/parseBigInt.ts(60,23): error TS1177: Binary digit expected.
88
tests/cases/compiler/parseBigInt.ts(61,20): error TS1178: Octal digit expected.
99
tests/cases/compiler/parseBigInt.ts(62,20): error TS1125: Hexadecimal digit expected.
@@ -82,13 +82,13 @@ tests/cases/compiler/parseBigInt.ts(70,72): error TS2345: Argument of type '3' i
8282
!!! error TS1005: ',' expected.
8383
{ const scientific = 1e2n; }
8484
~
85-
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
85+
!!! error TS1352: A bigint literal cannot use exponential notation.
8686
{ const decimal = 4.1n; }
8787
~
88-
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
88+
!!! error TS1353: A bigint literal must be an integer.
8989
{ const leadingDecimal = .1n; }
9090
~
91-
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
91+
!!! error TS1353: A bigint literal must be an integer.
9292
const emptyBinary = 0bn; // should error but infer 0n
9393

9494
!!! error TS1177: Binary digit expected.

0 commit comments

Comments
 (0)