Skip to content

Defer number literal evaluation to parser#4516

Open
nsvke wants to merge 1 commit intoRust-GCC:masterfrom
nsvke:refactor-number-literal-lex
Open

Defer number literal evaluation to parser#4516
nsvke wants to merge 1 commit intoRust-GCC:masterfrom
nsvke:refactor-number-literal-lex

Conversation

@nsvke
Copy link
Copy Markdown
Contributor

@nsvke nsvke commented Apr 6, 2026

This PR defers number literal evaluation (underscore stripping, base conversion) and suffix validation from the Lexer to the Parser phase.

Previously, the Lexer eagerly stripped underscores and validated suffixes. This violated source fidelity for procedural macros, causing them to receive mutated strings or fail prematurely on invalid suffixes.

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Update Token::make_int and Token::make_float calls to include suffix_start and LITERALBASE_DECIMAL.
* expand/rust-macro-builtins-location.cc (MacroBuiltin::column_handler): Pass string length and base to Token::make_int. (MacroBuiltin::line_handler): Likewise.
* lex/rust-lex.cc (Lexer::parse_in_type_suffix): Rename to parse_in_suffix and return string instead of PrimitiveCoreType. (Lexer::parse_in_suffix): Remove underscore stripping to preserve source fidelity for macros. (Lexer::parse_in_exponent_part): Preserve '+' and '-' characters in the raw string. (Lexer::parse_in_decimal): Remove underscore stripping. (Lexer::parse_non_decimal_int_literal): Track suffix start index and pass literal base. (Lexer::parse_non_decimal_int_literals): Use IntegerLiteralBase enum values instead of raw integers. (Lexer::parse_decimal_int_or_float): Track suffix string length and pass base parameters to token creation.
* lex/rust-lex.h: Update method signatures for suffix parsing.
* lex/rust-token.h (enum IntegerLiteralBase): New enum to represent numeric bases.
* parse/rust-parse-impl-expr.hxx: use LiteralResolve functions to evaluate raw token strings.
* parse/rust-parse-impl-pattern.hxx: Use evaluated literal strings for INT and FLOAT tokens.
* parse/rust-parse.cc (resolve_literal_suffix): Move suffix validation logic from lexer to parser. (evaluate_integer_literal): New function to strip underscores and convert to decimal via GMP. (evaluate_float_literal): New function to strip underscores from floats.
* parse/rust-parse.h (evaluate_integer_literal): Declare in LiteralResolve namespace. (evaluate_float_literal): Likewise. (resolve_literal_suffix): Likewise.
* util/rust-token-converter.cc (from_literal): Safely reconstruct raw text and suffix to dynamically determine base and suffix_start for ProcMacros.

gcc/testsuite/ChangeLog:

* rust/compile/deferred-suffix-validation.rs: New test.
* rust/compile/evaluate-integer-or-float.rs: New test.
* rust/compile/tuple-index.rs: New test.

Number literal evaluation and suffix validation should be done after macro expansion,
so we defer these to the parser phase. This preserves source fidelity for macro token
trees.

gcc/rust/ChangeLog:

	* ast/rust-ast-collector.cc (TokenCollector::visit): Update Token::make_int and
	Token::make_float calls to include suffix_start and LITERALBASE_DECIMAL.
	* expand/rust-macro-builtins-location.cc (MacroBuiltin::column_handler): Pass string
	length and base to Token::make_int.
	(MacroBuiltin::line_handler): Likewise.
	* lex/rust-lex.cc (Lexer::parse_in_type_suffix): Rename to parse_in_suffix and return
	string instead of PrimitiveCoreType.
	(Lexer::parse_in_suffix): Remove underscore stripping to preserve source fidelity for
	macros.
	(Lexer::parse_in_exponent_part): Preserve '+' and '-' characters in the raw string.
	(Lexer::parse_in_decimal): Remove underscore stripping.
	(Lexer::parse_non_decimal_int_literal): Track suffix start index and pass literal base.
	(Lexer::parse_non_decimal_int_literals): Use IntegerLiteralBase enum values instead of
	raw integers.
	(Lexer::parse_decimal_int_or_float): Track suffix string length and pass base parameters
	to token creation.
	* lex/rust-lex.h: Update method signatures for suffix parsing.
	* lex/rust-token.h (enum IntegerLiteralBase): New enum to represent numeric bases.
	* parse/rust-parse-impl-expr.hxx: use LiteralResolve functions to evaluate raw token
	strings.
	* parse/rust-parse-impl-pattern.hxx: Use evaluated literal strings for INT and FLOAT
	tokens.
	* parse/rust-parse.cc (resolve_literal_suffix): Move suffix validation logic from lexer
	to parser.
	(evaluate_integer_literal): New function to strip underscores and convert to decimal via
	GMP.
	(evaluate_float_literal): New function to strip underscores from floats.
	* parse/rust-parse.h (evaluate_integer_literal): Declare in LiteralResolve namespace.
	(evaluate_float_literal): Likewise.
	(resolve_literal_suffix): Likewise.
	* util/rust-token-converter.cc (from_literal): Safely reconstruct raw text and suffix to
	dynamically determine base and suffix_start for ProcMacros.

gcc/testsuite/ChangeLog:

	* rust/compile/deferred-suffix-validation.rs: New test.
	* rust/compile/evaluate-integer-or-float.rs: New test.
	* rust/compile/tuple-index.rs: New test.

Signed-off-by: Enes Cevik <nsvke@proton.me>
@powerboat9 powerboat9 requested review from CohenArthur and P-E-P and removed request for P-E-P April 9, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants