Skip to content

type-checker/DX: integer literals don't coerce to i64 in operator/argument/return positions #219

@0xGeorgii

Description

@0xGeorgii

Summary

An integer literal is typed i32 with no implicit widening and no cast operator, so literals fail to combine with i64 values in most expression positions. Yet the same literals coerce fine in let-with-annotation and struct/array field initializers. The result is that nearly every i64 constant must be hoisted into its own let, which is heavy boilerplate for any fixed-point / i64-centric code.

Where literals do NOT coerce (all fail with i64 vs i32)

pub fn f(a: i64) -> i64 { return a << 16; }      // Shl operands differ: i64 vs i32
pub fn g(a: i64) -> i64 { return a + 65536; }     // Add operands differ
pub fn h(a: i64) -> i64 { if a < 65536 { ... } }  // Lt operands differ
pub fn k(a: i64) -> i64 { return id(a, 65536); }  // arg 2 expected i64, found i32
pub fn m() -> i64 { return 65536; }               // return: expected i64, found i32
pub fn n() -> i64 { return -42; }                 // unary minus literal: i32

Where they DO coerce

let x: i64 = 65536;                 // ok (let annotation)
let v: Vec3 = Vec3 { x: 65536 };    // ok (struct field init)
let a: [i64; 2] = [1, 2];           // ok (array element init)

Also: no integer-literal suffix parses

pub fn f(a: i64) -> i64 { return a << 16i64; }   // parse error
pub fn g(a: i64) -> i64 { return a << 16_i64; }  // parse error

Impact

The only way to get an i64 constant into an operator/argument/return is to bind it first:

// instead of  (a * b) >> 16
let sh: i64 = 16;
return (a * b) >> sh;

In fixed-point code (Q16.16, everything i64) this means a let n: i64 = …; preamble for essentially every numeric constant — a large, repetitive tax that also hurts readability.

Suggested directions

  • Propagate the expected type into operands of binary ops, call arguments, and return expressions (bidirectional checking), so a literal unifies with the i64 it's used against — the same coercion already applied at let/field initializers.
  • And/or support typed integer-literal suffixes (16i64, 16_i64).

Environment: infc 0.0.1 (commit df45600, ABI 1.0), Inferara/inference @ d82d935 (wasm-linker). Found while implementing a fixed-point ray tracer entirely in Inference (scratch/raytracing-in-one-weekend).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsyntaxInference syntax related

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions