Skip to main content

lower_service_handler_signature_ir

Function lower_service_handler_signature_ir 

Source
pub fn lower_service_handler_signature_ir(
    h: &Handler,
    program: &CheckedProgram,
) -> HandlerSignatureIr
Expand description

#1187’s slice 5 (the Service emitter cutover): emit_service’s own standalone entry point for a handler’s resolved signature only — params/ret/effectful, never the body. Deliberately does not build a real IrHandler/bynk_ir::IrItem::Service: both lower_handler_ir/lower_service_handler_ir unconditionally lower the handler’s own body into a real IrExpr (IrHandler::body is not Option), and an ordinary from http handler’s body routinely uses ? propagation (ExprKind::Question) or an is-expression (ExprKind::Is). Correction (P6.25, 2026-08-19): both landedQuestion as P6.15 (ADR 0337, lower_question_ir, decomposing to IrExprKind::Match per #1225’s own Ok/Err/Some/None identity precedent) and Is as P6.16 (ADR 0338, lower_is_ir, a forced-temp Let discharging R5.10). Neither is reached from this call site or any other shipped emitter path yet — emitter/lower.rs’s own P6.2 Call/Lambda cutover hasn’t landed — so the reasoning below (a real IrHandler here would still panic on other, still-unconverted constructs reachable from an ordinary from http body) stands, just not on Question/Is specifically anymore. Building a real IrHandler at emit_service’s own call site would panic on exactly the ordinary Http services this slice needs to keep working. Mirrors body_writes_state’s own precedent (#1196): a narrow, standalone reader of already-resolved data, not the full IrItem/IrHandler assembly — the same posture, applied to signature data instead of a single boolean. Deliberately not lower_handler_signature_ir(h, &cx) (review of #1198) — that helper’s own ADR 0334 .unwrap_or_else(|| panic!(..)) on a resolution miss is correct for an agent handler (the checker guarantees resolution there) but not for a service one: resolver.rs skips CommonsItem::Service in every type-ref-resolution pass, check_handler_body silently skips a param whose type doesn’t resolve and silently returns on an unresolvable return type (no diagnostic either way), and check_http_handler only constrains a param’s name (path segment or body), never validates a body: param’s own declared type. A service handler naming an undeclared type certifies today (and previously just emitted that bad name verbatim, a tsc-only failure) — reusing the strict helper here would turn that pre-existing, real-but-harmless-to-the-compiler gap into an ICE on the production emit path for every service in every project (confirmed live: on POST("/x") (body: Nope) -> Effect[HttpResult[String]] by v: Visitor { ... } panics bynkc before this fix). Mirrors lower_protocol_ir’s own Ty::Unit-on-miss posture, for the identical underlying reason (that function’s own doc comment already documents the checker’s Service-wide resolution gap).

effectful is computed from h.return_type’s own AST shape (TypeRef::Effect(..), matching is_effectful_return exactly), not from the resolved ret’s Ty::Effect(_) shape — a resolution miss on ret (falling back to Ty::Unit below) must not silently flip an Effect[Nope]-returning handler to non-effectful; the top-level Effect[...] wrapper is always syntactically determinable regardless of whether its own inner type resolves.