Skip to content

P6.x: convert emitter::block_uses_emit to read the checker's own resolved Callee - #1203

Merged
accuser merged 2 commits into
mainfrom
p6-block-uses-emit-callee
Aug 14, 2026
Merged

P6.x: convert emitter::block_uses_emit to read the checker's own resolved Callee#1203
accuser merged 2 commits into
mainfrom
p6-block-uses-emit-callee

Conversation

@accuser

@accuser accuser commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Scope: emitter::block_uses_emit — the per-handler twin deciding emit_service/emit_agent's
    own deps.__eventsDispatch parameter threading — now reads the checker's own resolved
    Callee::Capability{cap:"Events",op:"emit"} instead of matching a bare Ident("Events") receiver by
    name.
  • Addresses: the real inconsistency P6.x: thread per-unit Callee data forward; convert unit_table_uses_emit and called_cross_context_services #1202's own review found and documented in a code comment,
    not left silent.
  • Realises: the two Events-detection checks (unit_table_uses_emit, project-wide, and
    block_uses_emit, per-handler) now fully agree on every input.

The inconsistency this closes

Before #1202, both unit_table_uses_emit (project.rs) and block_uses_emit (emitter.rs) matched a
bare Ident("Events") receiver by name — the same syntactic approach, both accepted as a deliberate
"approximation" per block_uses_emit's own prior doc comment (mirroring block_uses_send's sibling
precedent). #1202 converted unit_table_uses_emit to read the checker's own resolved Callee, but left
block_uses_emit untouched — its own review caught this and documented it explicitly rather than
papering over it with a fixture that would have failed tsc --strict.

A locally-declared type also named Events with its own static emit method (legal Bynk, resolves to
Callee::Static, not Callee::Capability) makes the two disagree: unit_table_uses_emit correctly
skips compose/fan-out generation, while block_uses_emit still threads a deps.__eventsDispatch
parameter with nothing left to supply it — a real tsc type error, not just cosmetic drift.

Why this was mechanical, unlike #1202's own project.rs plumbing

Every one of block_uses_emit's callers already had a TypedCommons/CheckedProgram in scope —
emit_service/emit_agent take commons, the ir::lower callers take program. So this is purely a
signature change (block_uses_emit(b: &Block, callees: &HashMap<ExprId, Callee>) -> bool) plus
call-site threading — no new data-flow plumbing needed, unlike #1202's own RunChecks::Checked
threading. block_uses_send needs no matching conversion: a ~> send is a real Statement::Send AST
variant, not a method call that could be shadowed, so it was never approximate the way
block_uses_emit's method-name match was.

Correctness evidence

  • BYNK_BLESS=1 cargo test -p bynkc --test e2e bless_positive_fixtures touched zero existing files.
  • 1204_events_emit_shadowed_by_local_type — the exact shape that failed tsc --strict under
    P6.x: thread per-unit Callee data forward; convert unit_table_uses_emit and called_cross_context_services #1202 alone (found during that PR's own review, documented, deliberately not landed broken) — now
    compiles and passes tsc --strict clean. cargo test -p bynkc --test tsc_verify (real tsc --strict
    over every fixture's emitted output) is clean, including this one.
  • ast_importers unaffected (still 8).

cargo build --workspace / cargo clippy --workspace --all-targets / cargo fmt --all -- --check /
cargo test --workspace all clean (164 test-result blocks, 0 failures, including
emitted_typescript_passes_tsc_strict).

Done when

  • block_uses_emit reads Callee, not a bare-Ident name match.
  • All 10 call sites converted (emitter.rs, emitter/emit.rs ×7, ir/lower.rs ×3).
  • The fixture that exposed the disagreement now compiles and passes tsc --strict.
  • unit_table_uses_emit's own doc comment updated — the "known follow-on" it named in P6.x: thread per-unit Callee data forward; convert unit_table_uses_emit and called_cross_context_services #1202 is
    resolved, not just left stale.
  • block_uses_send confirmed not needing the same fix, with the reasoning stated.
  • ast_importers unaffected (still 8) — stated explicitly.
  • design/pending/p6-block-uses-emit-callee.md added (patch level — internal only, no language
    surface change beyond fixing a real tsc-failing edge case).
  • A new ADR records this decision if the reviewing bot calls for one; its number is assigned at merge.
    Part of Phase 6 — The IR (spine) #1137 — a further step toward project.rs's own slice 6 cleanup.

…lved Callee

Closes the real inconsistency #1202's own review found and documented (in
a code comment on unit_table_uses_emit, not silently): before this commit,
unit_table_uses_emit (project.rs, converted in #1202) read the checker's
resolved Callee::Capability{cap:"Events",op:"emit"}, while its per-handler
twin block_uses_emit (deciding emit_service/emit_agent's own
deps.__eventsDispatch parameter threading) still matched a bare
Ident("Events") receiver by name -- the same syntactic approach both used
before #1202, and both accepted as an "approximation" per this function's
own prior doc comment (matching block_uses_send's sibling precedent).

That approximation stopped being harmless the moment only one of the two
checks became precise: a locally-declared type also named `Events` with
its own static `emit` method (legal Bynk, resolves to Callee::Static, not
Callee::Capability) made the two disagree -- unit_table_uses_emit correctly
skips compose/fan-out generation, while block_uses_emit still threads a
deps.__eventsDispatch parameter with nothing left to supply it. Confirmed
with a real fixture: 1204_events_emit_shadowed_by_local_type failed
`tsc --strict` under #1202 alone (found during that PR's own review,
documented, deliberately not landed broken) and passes clean now that both
checks agree.

block_uses_emit's own callers all already had a TypedCommons/CheckedProgram
in scope (emit_service/emit_agent take `commons`, the ir::lower callers
take `program`), so this is purely a signature change plus call-site
threading -- no new plumbing needed, unlike #1202's own project.rs-level
fix. block_uses_send needs no matching conversion: a `~>` send is a real
Statement::Send AST variant, not a method call that could be shadowed, so
it was never approximate the way block_uses_emit's method-name match was.

Correctness evidence: BYNK_BLESS=1 cargo test -p bynkc --test e2e
bless_positive_fixtures touched zero existing files. `cargo test -p bynkc
--test tsc_verify` (tsc --strict over every fixture's real emitted output)
is clean, including the new fixture. ast_importers unaffected (still 8).

Part of #1137. A further step toward project.rs's own slice 6 cleanup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions
github-actions Bot marked this pull request as ready for review August 14, 2026 21:24
@accuser
accuser merged commit c4a037c into main Aug 14, 2026
25 checks passed
@accuser
accuser deleted the p6-block-uses-emit-callee branch August 14, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant