feat(typeck): support negative integer literal coercion #648
Merged
Conversation
This was referenced Dec 17, 2025
DaniPopes
pushed a commit
that referenced
this pull request
Dec 22, 2025
This enables distinguishing edge cases like 127 (fits in int8) from 128 (doesn't fit), which is needed for correct implicit and explicit integer conversions. - Changed internal storage from `u8` (bytes 0-32) to `u16` (bits 0-256) - `TypeSize::new()` now takes bits directly - Added `new_fb_bytes()` for fixed-bytes types that take byte counts - `bits()` returns stored value, `bytes()` computes `ceil(bits/8)` - `mk_ty_int_literal` no longer rounds to multiples of 8 Closes #650 Unblocks #647 #648 #649
addc964 to
e4c688d
Compare
1e5aea6 to
92db371
Compare
e4c688d to
d621ddf
Compare
92db371 to
54d1f87
Compare
DaniPopes
approved these changes
Dec 22, 2025
onbjerg
added a commit
that referenced
this pull request
Dec 22, 2025
Add implicit type coercion for integer literals (IntLiteral) to typed integers (uint/int). The coercion rules are: - IntLiteral -> uint: Allowed if the literal is non-negative and fits in the target size (size.bits() <= target.bits()) - IntLiteral -> int: Allowed with strict inequality (size.bits() < target.bits()) for non-negative values due to TypeSize rounding, and non-strict for negative values TypeSize stores ceil(bit_len/8), so int_literal[1] covers 0-255. This means we can't distinguish edge cases like 127 (fits in int8) from 128 (doesn't fit), so we conservatively require int16+ for int_literal[1]. Note: Negative literal support requires additional work in the type checker to propagate negativity through unary negation. This is provided in a follow up. Supercedes #564 and closes #627 (closes #564) Stack: - #647 (this) - #648 - #649
Implement proper handling of negative integer literals in the type checker. Previously, negative literals like -42 were broken because: 1. The parser represents them as unary negation applied to a positive literal, so type_of_lit only sees the positive value 2. The negativity flag in IntLiteral was always false This commit fixes the issue by: - Allowing unary negation on IntLiteral types (they can always be negated since the result is just a negative literal) - Propagating the negativity flag when applying unary negation to an IntLiteral, flipping neg from false to true - Not propagating the expected type through negation when targeting signed types, to avoid premature type mismatch errors on the inner expression Also simplifies the coercion rule to use strict inequality for both positive and negative literals, since TypeSize rounding means we can't reliably distinguish edge cases in either direction.
d621ddf to
6860eb9
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.
Implement proper handling of negative integer literals in the type checker. Previously, negative literals like -42 were broken because:
This commit fixes the issue by:
Also simplifies the coercion rule to use strict inequality for both positive and negative literals, since TypeSize rounding means we can't reliably distinguish edge cases in either direction.
On top of #647
Supercedes #566 (will mark @mablr as a co-author to commend effort) and closes #560 (closes #566)
Stack: