Skip to content

type-lowering follow-ups before main merge (from PR #5462 audit) #5464

Description

@proggeramlug

Follow-ups identified while auditing #5462 (squash-merged into `codex/type-lowering-runtime-20260616` as 4d8df5a). Neither blocks the feature branch, but both should be resolved before this work is promoted to `main`.

1. U32 packed-loop store is a hard-error landmine

`lower_packed_numeric_loop_store_value` does `bail!("packed-u32 loop stores are not implemented")` (`crates/perry-codegen/src/expr/index_set.rs:311`).

Currently unreachable — the U32 `PackedNumericLoopKind` only arises from read-only loops (`supported_packed_numeric_loop_store_kind` in `stmt/loops.rs:661` only ever returns `I32` or `F64`), so no `IndexSet` triggers the U32 arm. But a `bail!` here propagates as a whole-compile failure rather than a graceful fallback. If a future change ever routes a U32 store through this path, it will hard-error instead of degrading to the dynamic path.

Fix: return `None` / fall back to the runtime-keyed store instead of `bail!`.

2. Confirm Int32[] / PerryU32 fast/slow-path wrapping consistency

The new `expr_is_i32_shaped` classifies `>>>` (UShr) as `PackedI32` (`collectors/hir_facts.rs`). The i32 store/load fast paths use signed `sitofp`/`fptosi`, so a uint32 like `3_000_000_000` round-trips as `-1294967296`.

This is contained for plain `number[]` (both the store path in `stmt/loops.rs:661` and the load path at `loops.rs:556` are gated on `local_is_int32_array` — declared `Int32` element type — so `number[]` always takes the F64 path and stores the full value). For an explicitly-declared `Int32[]`, signed wrap is the correct Int32Array semantics.

Action: verify Perry's `Int32[]` and `PerryU32` slow paths wrap identically to these new fast paths, so fast/slow stay observably consistent. Add a regression test pinning the round-trip value for a `>>>`-produced > i32::MAX element in a declared `Int32[]`.


Source: audit of #5462. Both are minor/low-severity; the evidence gate and 185 codegen regression tests landed in that PR are solid and should remain the bar for the main-bound PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions