pub fn lower_store_field_ir(
f: &StoreField,
program: &CheckedProgram,
) -> StoreFieldIrExpand description
P6.7 (#1163): lower an agent store field declaration into a real
StoreFieldIr — dispatches on f.kind.head.name into
StoreKindIr’s five real variants; Queue cannot reach a certified
program (bynk.store.kind_unsupported gates it before certify, R3.10),
so this match is total over what one can actually contain, not a gap
needing its own extension later.
@ttl/@retain millis and @indexed(by: …) field names are read
directly off f.annotations, independently of cache_ttl_millis/
store_log_fields/store_map_indexes (bynk-check/the shipped
emitter) — the pattern is the same one those already established
([DECISION B]/[DECISION C], #1163), not a call into shared code: this
track’s own P6.0 precedent (design/tracks/the-ir.md §3.4, Q4) chose to
extend the checker’s typed output once (Callee) rather than let a
lowering pass re-derive from the AST the way the shipped emitter’s own
dispatcher does, and this constructor falls short of that bar — a real,
accepted duplication (three independent copies of the same
DurationLit-extraction shape now exist: context_checks.rs,
emitter/emit.rs, and here), not one this slice is positioned to close,
since none of the three is pub/shaped for a shared caller today. Within
this function the @ttl/@retain cases at least share one call each to
duration_millis_annotation, rather than repeating the extraction
inline a second time. indexed keeps the annotation’s own declaration
order, deduplicated — no sort, unlike the shipped emitter’s own
doubly-sorted HashMap intermediate ([DECISION E]’s own structural fix,
ir.rs’s own StoreFieldIr::indexed doc comment), but still guarding
against a duplicate by: key the checker admits (validate_indexed_keys
validates each by: argument independently, so @indexed(by: k, by: k)
certifies), mirroring the shipped emitter’s own store_map_indexes
dedup guard.
init is constructed only for a Cell field ([DECISION D]) — no
checker pass types a non-Cell field’s init expression (a real,
pre-existing gap this proposal’s own grounding pass found:
context_checks.rs’s init-checking loop skips anything that isn’t
Cell, and no other pass fills that gap either), so on a certified
program such an expression, if ever written, has no expr_types entry —
lowering it here would hit this pass’s own ADR 0334 panic on a value the
checker never verified, not a recoverable state.
Deliberately not unified with checker::StoreField (bynk-check/src/checker.rs):
that dispatch is ephemeral, per-agent checking-time scratch, rebuilt
fresh inside check_agent_decls and discarded once that agent’s
handler/invariant checking finishes; this constructor produces
persistent IR data with no consumer yet. Collapsing them would mean
either the checker producing IR-shaped data (crossing the phase-5/
phase-6 boundary the-ir.md §3.4 already drew deliberately) or this
pass consuming the checker’s own discarded scratch state across a value
that no longer exists once check_agent_decls returns — a real, named
duplication (#1163’s own Risks), not a gap this slice closes.