Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

Mixed-sign arithmetic lowers on both backends in member transforms and pure fn bodies. On EVM, a mixed-sign expression directly in a route body (a let value or return(...)) does not yet compile; compute it in a pure fn and call that from the route.

Rule 3 — u128 / U256 mixed with signed

There is no wider signed primitive than i128, so mixing u128 or U256 with any signed type in arithmetic has no common type and is rejected. Cast one side explicitly with as. (Comparisons are exact and allowed for u128; only U256 against a signed operand is rejected there.)

m_a: u128 + d: i8    // rejected
m_b: U256 + d: i32   // rejected

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 marks a rejected arithmetic combination (Rule 3).

u8u16u32u64u128U256i8i16i32i64i128
u8u8u16u32u64u128U256i16i16i32i64i128
u16u16u32u64u128U256i32i32i32i64i128
u32u32u64u128U256i64i64i64i64i128
u64u64u128U256i128i128i128i128i128
u128u128U256ERRERRERRERRERR
U256U256ERRERRERRERRERR
i8i8i16i32i64i128
i16i16i32i64i128
i32i32i64i128
i64i64i128
i128i128

Practical guidance

  • Prefer same-sign arithmetic so widening stays obvious.
  • Mixing u64 with signed values yields i128 — larger than most balance fields. On EVM, keep mixed-sign expressions out of route bodies (see Rule 2).
  • Do not mix u128 / U256 with 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.

See Checked vs Wrapping Arithmetic.