Skip to content

Defer number literal evaluation to parser#4516

Merged
P-E-P merged 1 commit into
Rust-GCC:masterfrom
nsvke:refactor-number-literal-lex
Apr 29, 2026
Merged

Defer number literal evaluation to parser#4516
P-E-P merged 1 commit into
Rust-GCC:masterfrom
nsvke:refactor-number-literal-lex

Conversation

@nsvke

@nsvke nsvke commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

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.

@powerboat9 powerboat9 requested review from CohenArthur and P-E-P and removed request for P-E-P April 9, 2026 04:29

@CohenArthur CohenArthur left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a really good fix and the implementation looks good! well done @nsvke!

Comment thread gcc/rust/lex/rust-token.h Outdated
@nsvke nsvke force-pushed the refactor-number-literal-lex branch from 1b5fdc5 to 5d4ec59 Compare April 29, 2026 08:30
Comment thread gcc/testsuite/rust/compile/tuple-index.rs Outdated
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 IntegerLiteralBase::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 class 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>
@nsvke nsvke force-pushed the refactor-number-literal-lex branch from 5d4ec59 to 26883b4 Compare April 29, 2026 09:00
@P-E-P P-E-P added this pull request to the merge queue Apr 29, 2026
Merged via the queue into Rust-GCC:master with commit b89cf0b Apr 29, 2026
12 checks passed
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.

4 participants