feat(slang): integer literal narrowing#367
Merged
hedgar2017 merged 3 commits intomainfrom Apr 28, 2026
Merged
Conversation
2b61295 to
b81c7c1
Compare
b81c7c1 to
774685d
Compare
774685d to
797530c
Compare
797530c to
f82eebd
Compare
There was a problem hiding this comment.
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)(plusemit_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. |
c7dae05 to
c0b1865
Compare
c0b1865 to
6dc32a6
Compare
b3d377b to
9bb051f
Compare
4c470c5 to
4fc629e
Compare
abinavpp
approved these changes
Apr 28, 2026
Contributor
abinavpp
left a comment
There was a problem hiding this comment.
thank you! not sure if we already have a lit test for this.
Contributor
Author
|
@abinavpp thanks, lemme check and see if I can add a couple just in case! |
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).
f86b569 to
d080086
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
decimal.value(),hex.value(),literal_type.kind()— no more reaching into slang's evaluator orir_nodefields.Builder::emit_constant(&BigInt, Type)for all integer constants — dispatches tosol.address_cast,arith.constant, orsol.constantby target type.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/daysunits, zero, negativeint8literals, boolean keywords.tests/solidity/simple/constant_expressions/rational_literals.sol—0.5 minutes,0.5 gwei,0.25 ether,0.5 ether,1.5 ether,1e3,1.5e3,1e18.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::testregresses from PASS to FAIL. Slang's binder does not fold binary expressions of literal operands, so the narrowed leaf widths (1 : ui8,100 : ui8) cause1 << 100and similar constant subexpressions to overflow at 8-bit width. The previous code masked this by mapping everyLiteralKindto ui256. Tracked by a TODO inresolve_expression_type; proper fix is constant-expression folding either upstream in slang's binder (matching solc'sRationalNumberType::binaryOperatorResult) or locally in solx-slang.