Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,29 @@ Cleared (prior PR #521): `DerivedOpEffect { method, path_template, shape }` coll

**Stage 1e.0 closeout — pattern-role authority structural** → ✅ Structurally resolved for the live single-role state (`VectorList` only): list-pattern lowering does not dispatch on a host `PatternStrategy` enum in emitters — each `spec/{rust,go,python}.dag` `*_list_pattern` declares `strategy: VectorList` plus the template bundle; Rust/Go/Python emitters validate that tag fail-closed when indexing realizations and render from the loaded templates only (`src/v3/std/emit_model.dag` documents the split). When a second distinct lowering path ships, restore strategy on the emitter binding and branch in render (still fail-closed from spec rows), and extend `PatternStrategy` + `spec/*.dag` data — YAGNI until then.

### Lane 1 Stage 1e tail — SG-7 emit cutover (active, SG-program owned)

**Scope.** SG-7 is the SG-program lane that dissolves `src/v3/compiler/src/emit/rust_target.rs` (≈5.5K hand-authored lines) and `src/v3/compiler/src/emit/python_target.rs` (≈2K hand-authored lines) into spec-driven declarations in `src/v3/spec/{rust,python}.dag`, consumed by the shared `emit.rs` walker (already on main via Go's port). Per SG program rule, each migrated `.rs` file ends its diff either deleted, generated, or reduced to a narrow host shim — no dual-authority period. SG-7 IS the Rust/Python half of remaining Stage 1e walker-body dissolution; it is not a separate effort tracked in parallel.

**Sub-lane labeling.** XL-XXL size makes single-PR landing unlikely; ship partial with explicit sub-lane labels:

- **SG-7.1 — `emit/rust_target.rs` cutover.** Active sub-lane.
- **SG-7.2 — `emit/python_target.rs` cutover.** Sequenced after SG-7.1 settles (smaller surface, post-Python Stage 1e.0 bridge clear).

Each sub-PR must reduce handwritten-Rust line count in `src/v3/compiler/src/emit/` net-down vs. its base.

**Coordination (recorded per director clarification).** SG-program (`clever-swift` manager) owns Stage 1e Rust/Python walker-body dissolution via SG-7 — not the Features manager. `warm-wren` focuses on Stage 3b parse/apply tail and feature work, NOT `emit/*_target.rs`. Overlap on these files while SG-7 is in flight is a coordination failure to escalate to director, not resolve in-PR.

**Dependencies.**

- **SG-0 ratchet soundness (in flight, #559)** — affects trust in the handwritten-Rust census but does NOT block authoring or merging SG-7 sub-PRs. The census can back-fill verification once it lands.
- **Stage 1e Rust dissolution** — not a separate prerequisite; it IS SG-7's scope.
- **Pre-existing on main, not blockers:** `emit.rs` shared walker (#542 + #547) and `spec/rust.dag` / `spec/python.dag` carriers (active Stage 1e work).

**Explicit non-goal.** **Do not** ship a PR whose only handwritten-Rust reduction is porting the 23-line target facades (`emit_rust.rs`, `emit_python.rs`, `emit_go.rs`). They carry zero target heuristic authority; deleting them alone moves the SG-0 census without moving the thesis acceptance ("all target behavior is spec-driven, no per-target heuristic authority remains in handwritten Rust"). SG-7's cutover is the walker, not the facade.

**Cross-references:** `docs/emit-bridges.md` (bridge inventory), `docs/phase1-lane3-consolidation-build-plan.md` §"Wrapper exception receipt," `src/v3/SELF_HOSTING.md` §3 (Stage 1 emit.dag design note).

### Cross-cutting — performance

**Deferral: self-compile perf ratchet investigation (M, not on any critical path but compounding).** Self-compile time drifted from ~60s to ~70s in recent cycles (~16% growth). The ratchet keeps getting bumped without a root-cause investigation; each bump normalizes the regression. Scope: (1) profile a single `cargo test -p v3-compiler-tests` run, identify the top hot paths; (2) measure where the 10s came from across recent PRs (bisect across #479, #489, #490 if signal is unclear); (3) either fix the regression or document it as an accepted cost with a new ratchet ceiling. **Yellow-flag threshold: 90s.** If self-compile exceeds that before this deferral is scheduled, it preempts other work. No design doc needed; profiling is a data-gathering exercise.
Expand Down
12 changes: 7 additions & 5 deletions docs/emit-bridges.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,13 @@ The earlier **“≥ 86 sites”** lane estimate used a looser union/overlap men

---

### B15 — Hardcoded Rust attributes / derives
### B15 — Hardcoded Rust attributes / derives → ✅ Dissolved (SG-7.1)

| Where | What | Dissolution |
| Where | What | Resolution |
|-------|------|-------------|
| `emit_rust.rs` `render_type_declaration` | Prepends `"#[derive(Clone, Debug)]\n"` before struct/enum templates | **P0:** `TypeDefinitionSyntax` gains **attribute template list** or `record_derive` carriers (see `spec-field-gaps.md` §2). |
| `emit/rust_target.rs` `render_type_declaration` (was `emit_rust.rs`) | Previously prepended `"#[derive(Clone, Debug)]\n"` before struct/enum templates | **Dissolved in SG-7.1**: `spec/rust.dag` now bakes the derive line into `rust_type_defs.struct_def` and `rust_type_defs.enum_def` templates directly; the Rust emitter is a pass-through `render_named_template` with no target-specific prelude. If future Rust types need different derives, the authority is the spec template, not hand-coded Rust. |

**Why no new `record_derive` carrier.** The emit-model's `TypeDefinitionSyntax` templates already treat target-specific scaffolding (e.g., `@dataclass\n` in Python, `type {name} struct { ... }` in Go) as part of the template string. Baking `#[derive(Clone, Debug)]\n` into Rust's `struct_def` / `enum_def` is consistent with that established pattern — no new substrate field required. If a future need emerges for conditional/per-type derive sets (e.g., `Copy` iff the type is copy-safe), that motivates a structural carrier; YAGNI until then.

---

Expand Down Expand Up @@ -177,13 +179,13 @@ These are **not** all separate “name bridges,” but they are **behavior bridg
| `LanguageSpec` discrimination | **Yes** | Use `language` refs — B11 largely closed. |
| List / optional **variant roles** | **Partial** | Need explicit metadata or spec fields (B13). |
| Canonical algebra fallback | **Partial** | `OrderedRing` name is the gap (B14). |
| Rust derive attributes | **No** | Hardcoded (B15). |
| Rust derive attributes | **Yes** | Baked into `spec/rust.dag` `rust_type_defs.struct_def` / `enum_def` templates; B15 dissolved in SG-7.1. |

---

## Suggested dissolution priority (for P2)

1. **B14** + **B15** + **Loop** (B19) — unblock “spec-complete” Rust/Go/Python.
1. **B14** + **Loop** (B19) — unblock “spec-complete” Rust/Go/Python. (B15 dissolved in SG-7.1.)
2. **B13** — remove cross-target string variant compares.
3. **B12**, **B16**, **B17**, **B18** — polish and de-string remaining bootstrap.

Expand Down
18 changes: 6 additions & 12 deletions src/v3/compiler/src/emit/rust_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4502,12 +4502,9 @@ impl<'a> Ctx<'a> {
.map(|field| self.render_struct_field(field))
.collect::<Result<Vec<_>, _>>()?;
let fields_joined = join_rendered(&fields, " ");
Ok(format!(
"#[derive(Clone, Debug)]\n{}",
render_named_template(
&self.indexes.syntax.type_definitions.struct_def,
&[("name", name), ("fields", &fields_joined)],
)
Ok(render_named_template(
&self.indexes.syntax.type_definitions.struct_def,
&[("name", name), ("fields", &fields_joined)],
))
}
TypeConnective::Disj { variants } => {
Expand All @@ -4516,12 +4513,9 @@ impl<'a> Ctx<'a> {
.map(|variant| self.render_enum_variant(variant))
.collect::<Result<Vec<_>, _>>()?;
let variants_joined = join_rendered(&rendered_variants, " ");
Ok(format!(
"#[derive(Clone, Debug)]\n{}",
render_named_template(
&self.indexes.syntax.type_definitions.enum_def,
&[("name", name), ("variants", &variants_joined)],
)
Ok(render_named_template(
&self.indexes.syntax.type_definitions.enum_def,
&[("name", name), ("variants", &variants_joined)],
))
}
_ => Err(EmitError::UnsupportedBehavior(format!(
Expand Down
4 changes: 2 additions & 2 deletions src/v3/spec/rust.dag
Original file line number Diff line number Diff line change
Expand Up @@ -939,9 +939,9 @@ data rust_type_applications: TypeApplicationSyntax = {
}

data rust_type_defs: TypeDefinitionSyntax = {
struct_def: "pub struct {name} { {fields} }"
struct_def: "#[derive(Clone, Debug)]\npub struct {name} { {fields} }"
struct_field: "pub {name}: {type},"
enum_def: "pub enum {name} { {variants} }"
enum_def: "#[derive(Clone, Debug)]\npub enum {name} { {variants} }"
enum_unit_variant: "{name},"
enum_data_variant: "{name} { {fields} },"
}
Expand Down
Loading