Type Widening
When an arithmetic or comparison expression mixes numeric types, Cambrian widens both operands to a common type that can represent every value of either operand. No explicit cast is required for ordinary same-sign mixes.
Rules
Rule 1 — Same sign
Result width is max(width); signedness is unchanged:
m_total: u128 + amount: u64 // amount widened to u128
m_x: i32 + m_y: i64 // m_x widened to i64
Rule 2 — Mixed signedness
Result is signed with
width = max(2 × unsigned_width, signed_width):
m_count: u32 + delta: i8 // both → i64
m_val: u64 + offset: i64 // both → i128
Doubling the unsigned width keeps the full unsigned range representable in the signed result.
Rule 3 — u128 / U256 mixed with signed
There is no wider signed primitive than i128. Mixing u128 or U256
with any signed type is a compile-time error:
m_a: u128 + d: i8 // ERROR
m_b: U256 + d: i32 // ERROR
Any unsigned type combined with U256 widens to U256. Integer literals
adapt automatically: m_balance + 1 with m_balance: U256 treats 1 as
U256.
Full widening table
Cell at row A, column B is the result of A op B. Symmetric cells are
omitted; ERR means compile-time error.
| u8 | u16 | u32 | u64 | u128 | U256 | i8 | i16 | i32 | i64 | i128 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| u8 | u8 | u16 | u32 | u64 | u128 | U256 | i16 | i16 | i32 | i64 | i128 |
| u16 | u16 | u32 | u64 | u128 | U256 | i32 | i32 | i32 | i64 | i128 | |
| u32 | u32 | u64 | u128 | U256 | i64 | i64 | i64 | i64 | i128 | ||
| u64 | u64 | u128 | U256 | i128 | i128 | i128 | i128 | i128 | |||
| u128 | u128 | U256 | ERR | ERR | ERR | ERR | ERR | ||||
| U256 | U256 | ERR | ERR | ERR | ERR | ERR | |||||
| i8 | i8 | i16 | i32 | i64 | i128 | ||||||
| i16 | i16 | i32 | i64 | i128 | |||||||
| i32 | i32 | i64 | i128 | ||||||||
| i64 | i64 | i128 | |||||||||
| i128 | i128 |
Practical guidance
- Prefer same-sign arithmetic so widening stays obvious.
- Mixing
u64with signed values yieldsi128— fine, but larger than most balance fields; cast deliberately if you need a narrower store. - Do not mix
u128/U256with signed types; cast one side first. - Widening applies to checked and wrapping operators alike; overflow checking (or wrap) happens on the result type after widening.