Skip to content

feat(slang): integer literal narrowing#367

Merged
hedgar2017 merged 3 commits intomainfrom
refactor-slang-literal-types
Apr 28, 2026
Merged

feat(slang): integer literal narrowing#367
hedgar2017 merged 3 commits intomainfrom
refactor-slang-literal-types

Conversation

@hedgar2017
Copy link
Copy Markdown
Contributor

@hedgar2017 hedgar2017 commented Apr 23, 2026

Consumes slang's new literal-typing accessors to narrow integer literal emission, replaces the digit-count width heuristic, and unifies constant emission through a single builder entry point.

What's new

  • Uses decimal.value(), hex.value(), literal_type.kind() — no more reaching into slang's evaluator or ir_node fields.
  • Single Builder::emit_constant(&BigInt, Type) for all integer constants — dispatches to sol.address_cast, arith.constant, or sol.constant by target type.
  • Deletes the text-based decimal/hex emitters, the boolean-specific helper, and the digit-count width heuristic.
  • Supports rational decimals that reduce to integers (1.5 ether, 0.5 gwei), scientific notation (1e18, 2.5e10), and signed negatives via slang's prefix-expression fold.

Depends on NomicFoundation/slang#1722.

Newly passing tests

  • tests/solidity/simple/constant_expressions/literal_types.sol — digit separators, underscored hex, address literal, ether/days units, zero, negative int8 literals, boolean keywords.
  • tests/solidity/simple/constant_expressions/rational_literals.sol0.5 minutes, 0.5 gwei, 0.25 ether, 0.5 ether, 1.5 ether, 1e3, 1.5e3, 1e18.
  • Six pre-existing tests recovered from the signed-negative path: loop/range_bound/{i8,i16,i32_lower,i64_lower}.sol::main, operator/arithmetic/exponentiation_i128_const.sol::{ordinar_positive,to_max}.

Known regression

  • constant_expressions/bitwise.sol::test regresses from PASS to FAIL. Slang's binder does not fold binary expressions of literal operands, so the narrowed leaf widths (1 : ui8, 100 : ui8) cause 1 << 100 and similar constant subexpressions to overflow at 8-bit width. The previous code masked this by mapping every LiteralKind to ui256. Tracked by a TODO in resolve_expression_type; proper fix is constant-expression folding either upstream in slang's binder (matching solc's RationalNumberType::binaryOperatorResult) or locally in solx-slang.

@hedgar2017 hedgar2017 added the ci:slang Trigger slang unit tests on PR label Apr 23, 2026
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch 5 times, most recently from 2b61295 to b81c7c1 Compare April 23, 2026 18:43
@hedgar2017 hedgar2017 changed the title refactor(slang): consume slang's literal type info for emission feat(slang): narrow literal types via slang's evaluator Apr 23, 2026
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch from b81c7c1 to 774685d Compare April 23, 2026 18:58
@hedgar2017 hedgar2017 requested review from Copilot and removed request for Copilot April 23, 2026 19:00
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch from 774685d to 797530c Compare April 23, 2026 19:01
@hedgar2017 hedgar2017 requested a review from Copilot April 23, 2026 19:01
@hedgar2017 hedgar2017 self-assigned this Apr 23, 2026
@hedgar2017 hedgar2017 marked this pull request as ready for review April 23, 2026 19:01
@hedgar2017 hedgar2017 changed the title feat(slang): narrow literal types via slang's evaluator feat(slang): integer literal narrowing Apr 23, 2026
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch from 797530c to f82eebd Compare April 23, 2026 19:06
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors Solidity literal lowering to route integer literal evaluation through Slang’s CompileConstantEvaluator and Slang literal width metadata, replacing local heuristics and per-format emitters. It also expands literal support to cover unit-multiplied rational decimals that fold to integers.

Changes:

  • Add a unified Builder::emit_constant(&BigInt, Type) (plus emit_bool) and update call sites to use it for integer/address/bool constants.
  • Switch decimal/hex literal lowering to Slang’s constant evaluator and resolve literal MLIR types via Slang’s literal-kind width metadata.
  • Add new Solidity test cases covering literal typing edge cases and rational unit literals; update Slang dependency rev and lockfile accordingly.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
solx-mlir/src/context/builder/mod.rs Introduces emit_constant(BigInt, Type) and emit_bool, consolidating constant emission and handling address/bool specially.
solx-slang/src/ast/contract/function/expression/mod.rs Uses Slang constant evaluator for decimal/hex literals and emits constants via the new builder API.
solx-slang/src/ast/contract/function/expression/call/type_conversion.rs Maps Slang literal kinds to narrower MLIR integer widths (including address/zero).
solx-slang/src/ast/contract/function/statement/control_flow.rs Replaces boolean constant emission with emit_bool.
solx-slang/src/ast/contract/function/expression/logical.rs Replaces boolean constant emission with emit_bool.
solx-slang/src/ast/contract/function/expression/arithmetic.rs Adjusts call sites for updated constant helpers and minor unwrap_or cleanup.
solx-slang/src/ast/contract/function/statement/mod.rs Minor unwrap_or cleanup for return-type fallback.
tests/solidity/simple/literal_types.sol New test coverage for literal typing (separators, hex underscores, address literal, units, negatives, booleans).
tests/solidity/simple/rational_literals.sol New test coverage for rational decimal literals with units that fold to integers.
solx-slang/Cargo.toml Adds num workspace dep and bumps slang_solidity git rev.
solx-mlir/Cargo.toml Adds num workspace dep.
Cargo.lock Updates lockfile for the new Slang rev and transitive dependency changes.

Comment thread solx-slang/src/ast/contract/function/expression/mod.rs Outdated
Comment thread solx-slang/src/ast/contract/function/expression/mod.rs
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch 3 times, most recently from c7dae05 to c0b1865 Compare April 24, 2026 05:07
@hedgar2017 hedgar2017 requested a review from Copilot April 24, 2026 05:08
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch from c0b1865 to 6dc32a6 Compare April 24, 2026 05:13
@hedgar2017 hedgar2017 requested review from a team April 24, 2026 05:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated no new comments.

@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch 2 times, most recently from b3d377b to 9bb051f Compare April 26, 2026 02:49
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch 3 times, most recently from 4c470c5 to 4fc629e Compare April 28, 2026 07:44
Copy link
Copy Markdown
Contributor

@abinavpp abinavpp left a comment

Choose a reason for hiding this comment

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

thank you! not sure if we already have a lit test for this.

@hedgar2017
Copy link
Copy Markdown
Contributor Author

@abinavpp thanks, lemme check and see if I can add a couple just in case!

@hedgar2017
Copy link
Copy Markdown
Contributor Author

@abinavpp added one for literals, thanks!

Replaces solx's digit-counting width heuristic and hand-built MLIR
attribute strings with slang's CompileConstantEvaluator and LiteralKind
width/sign info. Unifies integer constant emission through
Builder::emit_constant(&BigInt, Type), which dispatches to
sol.address_cast, arith.constant, or sol.constant by target type.
Narrows signed negative literals to their minimum signed width, and
lowers rational decimal literals (1.5 ether, 0.5 gwei) that reduce to
integers after unit multiplication.
Document the gap in slang's binder: binary expressions of literal
operands are typed by one operand instead of folding the value, so
constant subexpressions overflow at narrowed leaf widths.
Cover the four distinct emission paths the literal-narrowing rework
opens: address literal (sol.address_cast dispatch), negative int8
(signed prefix-fold), rational ether (0.5 ether folded to ui64), and
scientific notation (1e18 folded to ui64).
@hedgar2017 hedgar2017 force-pushed the refactor-slang-literal-types branch from f86b569 to d080086 Compare April 28, 2026 12:32
@hedgar2017 hedgar2017 enabled auto-merge April 28, 2026 12:32
@hedgar2017 hedgar2017 added this pull request to the merge queue Apr 28, 2026
Merged via the queue into main with commit e590ced Apr 28, 2026
50 checks passed
@hedgar2017 hedgar2017 deleted the refactor-slang-literal-types branch April 28, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:slang Trigger slang unit tests on PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants