Sibling articles under this feature previously restated requirements in inconsistent forms.
Stage ordering and lowering - Design model
Platform spec article
Stage ordering and lowering - Design model
Spec standingStandard
-
This feature hub owns normative MUST/SHOULD contract text for Stage ordering and lowering.
Context
Decision
This feature hub owns normative MUST/SHOULD contract text. Sibling articles must not redefine hub requirements and should link here for authority.
Consequences
Contract changes start on the hub or in linked ADRs, then propagate to articles and implementation anchors.
Verification anchors
site/website/src/content/docs/platform-spec/compiler/build-pipeline/stage-ordering/index.mdxarticle bundle under the same feature directory.
-
Platform-spec text supersedes informal crate comments for Stage ordering and lowering.
Context
Implementation crates accumulated informal notes that diverged from published contracts.
Decision
Normative platform-spec prose and ADRs under this feature supersede informal comments in implementation crates until explicitly migrated into spec text.
Consequences
Engineers file spec/ADR updates when behavior changes; crate comments are non-authoritative for conformance arguments.
Verification anchors
compiler/crates/beskid_analysis/
-
Pipeline ordering was fragmented across crates before `beskid_pipeline` phase ids.
Context
Reference compiler must emit stable
beskid_pipelinephase events from parse throughlower.readywithout reordering semantic gates relative to mod boundaries.Decision
Phase literals are defined in
compiler/crates/beskid_pipeline/src/phases.rsand asserted by conformance tests; CLI/LSP observers rely on the same ids.Consequences
Reordering phases requires an ADR and registry updates.
Verification anchors
compiler/crates/beskid_pipeline/compiler/crates/beskid_analysis/src/services.rs.
- Stage ordering and lowering - Contracts and edge cases Required ordering guarantees and behavior under parse or semantic failures.
- Stage ordering and lowering - Design model Pipeline stage model and artifact boundaries for the reference compiler.
- Stage ordering and lowering - Examples Newcomer-oriented examples of pipeline execution order and failure points.
- Stage ordering and lowering - FAQ and troubleshooting Troubleshooting guide for stage ordering assumptions in build and run commands.
- Stage ordering and lowering - Flow and algorithm Ordered lowering algorithm used by build and run command paths.
- Stage ordering and lowering - Verification and traceability Source and test anchors that verify lowering order and backend artifact handoff.
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
Phase handoff model
Section titled “Phase handoff model”flowchart LR resolve_input[resolve_input] assemble[program.assemble] parse[parse] macro[macro.expand] modload[mod.load collect generate] semantic[semantic rules] comp[composition.resolve] modar[mod.analyze rewrite] hir[HIR and ModuleIndex] lower[lower_program] artifact[CodegenArtifact] resolve_input --> assemble --> parse --> macro --> modload --> semantic --> comp --> modar --> hir --> lower --> artifact
The compile model has a strict handoff chain:
resolve_input -> program.assemble -> parse (entry + indexed units) -> macro.expand -> mod collect/generate (when enabled) -> semantic rules gate -> composition.resolve (app host DI; see Native dependency injection) -> analyzer/rewriter passes -> HIR normalization -> resolution (with ModuleIndex) -> typing -> lower_program -> CodegenArtifact.
Backends (JIT and AOT) consume this artifact and must not reorder semantic phases.
Language macro expansion
Section titled “Language macro expansion”Language macros expand in macro.expand, immediately after parse and before mod.load. The phase:
- Resolves
name!invocations to in-scopemacrodefinitions. - Substitutes fragment arguments for
$paramin macro bodies (typed AST only). - Repeats until no invocations remain or
maxMacroExpansionDepth(default 32) is exceeded.
When mod.generate re-parses merged syntax, hosts must run macro.expand again before the next mod.collect / semantic gate (same syntax generation). Emit syntax.generation when either macros or mods mutate the program snapshot.
Mod phases and stable phase identifiers
Section titled “Mod phases and stable phase identifiers”Compiler mods (see Compiler Mods) run as explicit host-driven phases after macro.expand and before lowering.
- Phase vocabulary — Register stable string ids in
compiler/crates/beskid_pipeline/src/phases.rsand updatePIPELINE.mdin the same change. - Observer parity — CLI and codegen entrypoints must bracket mod phases with
PhaseStart/PhaseEnd(or documentedWorkUnitids). - Bounded generation —
Generatoris incremental by default and runs with a bounded replay loop (maxGeneratorRounds). On each replay, host merges typed AST contributions and re-parses affected units. - Analyzer/rewrite ordering —
Analyzerruns on merged host+generated code;Rewriterapplies typed replacements and is surfaced as fix-oriented behavior. - No lowering on torn trees — lowering runs only on a consistent post-merge snapshot.
Placement relative to beskid_codegen services
Section titled “Placement relative to beskid_codegen services”The reference lowering path orders parse, semantic diagnostics, lower, and codegen. Mod phases are inserted after parse: collect/generate, then semantic, then analyze/rewrite, then lowering.
Normative mod phase id strings (beskid_pipeline)
Section titled “Normative mod phase id strings (beskid_pipeline)”These literals must match Compiler Mods / Mod projects and pipeline phase ids.
Full build (FULL_BUILD_PHASE_ORDER) — After parse, insert macro.expand, then mod.load, mod.collect, mod.generate (plus syntax.generation on replay), then semantic phases, then mod.analyze, optional mod.rewrite, then lower/codegen/link.
JIT run (JIT_RUN_PHASE_ORDER) — No JIT mod execution path is normative for compiler mods; mod execution is AOT-hosted only.
Auxiliary ids — workspace.graph_changed and semantic.snapshot are emitted by workspace refresh and semantic pipeline orchestration respectively; they must use the same string literals when represented as phases (or as documented WorkUnit id prefixes if only work units are used—pick one representation per id and document it in PIPELINE.md).
lower.ready — Emitted immediately before the existing lower phase entrypoint runs on a merged program; hosts must emit it even when no mods ran (no-op instant) so observers can assert ordering uniformly.