fix: preserve full 256-bit precision for integer literals#55
Merged
Conversation
✅ Deploy Preview for edgelang ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Collaborator
|
lgtm pending merge of main and resolution of that conflict |
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.
Summary
Fixes #40 — Integer literals >2^64 were silently truncated to
u64.Also upgrades typeck const evaluation from
u64to fullU256precision.Commit 1:
fix: preserve full 256-bit precision for integer literalsProblem
Lit::Int(u64)in the AST meant the parser accumulated lexer bytes intou128then cast tou64, destroying precision. Any literal value above18,446,744,073,709,551,615was silently wrong — blockingMAX_UINT, realistic token amounts (e.g. 10^21 wei), and address literals.The lexer already produced correct
[u8; 32]big-endian bytes viadecimal_to_bytes32(). The parser threw them away.Fix
Lit::Int(u64, ...)→Lit::Int([u8; 32], ...)— carry raw bytes through the ASTu128→u64accumulationSmallInt(i64)(same path as before), values ≥2^63 useLargeInt(hex_string)which codegen already handles correctlyeval_const_expr— overflow guard for values >u64 (superseded by commit 2)No behavioral change for small values — values 0 to 2^63-1 follow the exact same
SmallIntcode path.Tests added (commit 1)
Commit 2:
feat(typeck): upgrade const eval to full U256 precisionProblem
eval_const_exprworked onu64— constants >2^64 returned 0, arithmetic overflowed at 10^19, and shifts were masked with& 63instead of% 256.Fix
ConstValue.value:u64→[u8; 32](big-endian 256-bit)eval_const_expr: rewritten to useruint::aliases::U256arithmetic internallyr >= 256→ return zero (correct EVM behavior)is_zero()guardLit::Intpasses[u8; 32]through directly — no truncationLit::Hex/Binproperly pads into 32 bytesSelf-contained in typeck —
ConstValueis not consumed outside the typeck crate. IR lowering re-evaluates constants from AST expressions independently.Tests added (commit 2)
All 670+ workspace tests pass.