pub fn lower_blanket_into(module: AIRNode) -> AIRNodeExpand description
Run the shared temp-hoist desugar over a fully-lowered, type-checked AIR module, returning the rewritten module. Idempotent on trees with no value-position diverging control flow (returns an equivalent tree).
This is a codegen pre-pass: it runs after type-checking and the
ownership/effect/capability analyses (so they never see the synthesised
declare-only bindings) and before every backend emits, making the rewrite
shared once across all five targets. It deliberately lives here rather than
in bock-air’s S-AIR lowering because the synthesised temp’s type is only
derivable at codegen (e.g. Go infers it structurally from the relocated
control-flow node), and to keep the interpreter and semantic analyses out of
the blast radius.
Codegen pre-pass: rewrite every derived-blanket recv.into() call in
module into the resolvable associated call Target.from(recv).
A derived blanket Into[Target] for Source is the bodyless reverse impl the
compiler synthesizes from a user impl From[Source] for Target. It is
unexecutable if emitted as an ordinary method call — the AIR lowers
recv.into() to Call(FieldAccess(recv, "into"), [recv]), which dispatches
to a non-existent into method on every compiled target (JS recv.into is not a function, etc.). The executable form is Target.from(recv) — the
from associated function each backend emits for the From impl.
Run after type-checking (in each backend’s generate_*), so a .into()
that reaches this pass has already resolved to a valid Into target: an
unrelated-target .into() was rejected at check time (E4012) and never
arrives here. The pass fires only when the module declares exactly one
distinct From target, making the rewrite’s target unambiguous (the
documented v1 single-conversion scope). With zero or several From impls it
is a no-op, leaving the call to its existing lowering. The rewritten Call
is stamped bock_air::lower::ASSOC_CALL_META_KEY so the backends emit the
static / free-function from call.