Skip to content

fix(gen): compile all 102 generated Rust modules and gate the corpus - #409

Open
dmitrii-f-t27 wants to merge 1 commit into
gHashTag:mainfrom
dmitrii-f-t27:fix/rust-corpus-399
Open

dmitrii-f-t27 wants to merge 1 commit into
gHashTag:mainfrom
dmitrii-f-t27:fix/rust-corpus-399

Conversation

@dmitrii-f-t27

@dmitrii-f-t27 dmitrii-f-t27 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Pipeline Compliance Checklist

What changed

A Rust 1.96 compile sweep of all 102 gen/rust artifacts found 92 passing on main (d6deeb3). The drift check stays green for the other ten because it compares text with the pinned t27c output and does not compile it.

Spec changes, regenerated with the unchanged compiler pin eb8b4208168557b36dca3a771f6901a5b10d9ef0:

  • E0384, E0594 (nine specs): these functions assigned to value parameters. Each one now copies the parameter into a local var and writes the copy. The generated C already passes arrays as structs by value, and the generated Zig already shadows the parameter, so no result changes. var keeps every typecheck warning count unchanged; let would add warnings.
  • E0308 (api_documenter): the array repeat count is now a literal [0; 16]. The declared [u32; MAX_PARAMETERS] type still fixes the length.
  • unused_comparisons (auto_config): five value >= 0 checks on u32 are removed. The E0594 errors had hidden them.
  • non_upper_case_globals (integration_framework): type_documentation is now TYPE_DOCUMENTATION. Nothing else references it.

Public argument and return types are unchanged.

New gate, which runs in the required build + test job:

  • tests/gen_rust_corpus_compiles.rs compiles every gen/rust/*.rs file as a separate crate with rustc --edition=2021 --crate-type=lib -D warnings. It uses the generated-module policy allow(clippy::all, unused) and a floor of 102 modules. First, it proves that five negative controls are rejected: E0384, E0594, E0308, unused_comparisons and non_upper_case_globals. It also proves that a valid control compiles.
  • tests/gen_rust_value_params.rs checks the results of every changed function. It also checks that the caller's arrays are unchanged.

Spec -> Code mapping

specs/{api_documenter,auto_config,bandwidth_allocator,cache_management,compression_engine,integration_framework,network_simulator,performance_profiler,topology_visualizer,traffic_animator}.t27 -> gen/{rust,zig,c}/<same>.{rs,zig,c}. The Rust files are committed rustfmt-formatted, because the new test includes them and cargo fmt --all --check covers them. The drift check normalizes both sides.

Validation (local, macOS arm64; CI runs on this PR)

  • The compiler pin was rebuilt locally. With it, all 284 committed artifacts reproduce: rust 102, zig 107, c 75 (the drift-guard procedure, with rustfmt-normalized Rust).
  • tools/regen.rs --check-staged: 30 staged artifacts verified.
  • Rust 1.96.0: cargo fmt --all --check and cargo clippy --all-targets -D warnings pass. The two new test targets pass: 2 + 7 tests. The corpus result is 102/102.
  • Control: with the ten main versions of the Rust artifacts restored, the gate fails on exactly those ten modules (92 of 102).
  • Zig 0.15.2 zig test and C -DT27_TEST_MAIN execute all the spec tests of the ten changed modules. t27c icarus-simulate passes for the ten specs. Typecheck warning counts are equal to the WARNBASE pins.
  • Differential check: 60,000 random and boundary-biased cases over the 20 changed functions. The old C from main, the new C and the new Rust give identical outputs. Eight spec mutants were regenerated, and the comparison detected each one. One more mutant is equivalent, because param_docs is never read.

Limits

  • The compiler pin is not updated. Upstream t27 already has both compiler fixes: fix(rust): preserve writes to by-value parameter bindings t27#5911 (mutable value parameters, 53dcd80f) and Rust array repetition must convert named integral counts to usize t27#5986 (typed repeat counts, 8f10d9b8). The pin is about 2,600 commits behind them. Moving it requires the full backend sweep that this issue requires. That work is separate. The explicit copies are valid t27 under either compiler.
  • The value semantics are kept as they are. Writes in age_cache, access_cache, remove_entry, set_config_value and similar functions still do not reach the caller. Changing that would change public return types.
  • Pre-existing hazards are not in scope. Some inputs index past the array: inject_fault with target_id >= 32, update_animation_packets with packet_count > 64 and calculate_circular_layout with node_count > 32. calculate_hierarchical_layout divides by zero when node_count < 4. Each of these panics in the generated Rust. All of them predate this change.
  • Host-only verification. This makes no radio or deployment claim.

Dmitrii Fedorov (@dmitrii-f-t27)

Ten generated Rust modules did not compile under rustc 1.96 with
-D warnings, although the drift check passed, because the drift check
only compares text with the pinned t27c output.

Spec changes, regenerated with the unchanged pin eb8b4208:
- Nine specs assigned to value parameters (E0384, E0594). Each such
  function now copies the parameter into a local `var` and writes the
  copy. This is the value semantics that the generated C (struct by
  value) and Zig (shadow) already had, so no result changes.
- api_documenter: the array repeat count is a literal, because the
  pinned Rust emitter copies a u32 count verbatim (E0308).
- auto_config: drop five `value >= 0` tests on u32 (unused_comparisons).
- integration_framework: rename type_documentation to
  TYPE_DOCUMENTATION (non_upper_case_globals).

Public argument and return types are unchanged. Typecheck warning
counts are unchanged for all ten specs.

tests/gen_rust_corpus_compiles.rs compiles every gen/rust module as its
own crate with -D warnings, enforces a floor of 102 modules, and first
proves that five negative controls (E0384, E0594, E0308,
unused_comparisons, non_upper_case_globals) are rejected.
tests/gen_rust_value_params.rs checks results and the caller contract
of the changed functions.

Closes gHashTag#399
@tri-claw

tri-claw Bot commented Oct 10, 2026

Copy link
Copy Markdown

Summary by t27-bees

Checked by the t27 compiler

t27c parse, parse-complete and typecheck on each changed .t27 file at 59f39b6. Nothing was generated, built or run. A pass means the file is well formed, not that it is right.

  • specs/api_documenter.t27: parses and typechecks.
  • specs/auto_config.t27: parses and typechecks.
  • specs/bandwidth_allocator.t27: parses and typechecks.
  • specs/cache_management.t27: parses and typechecks.
  • specs/compression_engine.t27: parses and typechecks.
  • specs/integration_framework.t27: parses and typechecks.
  • specs/network_simulator.t27: parses and typechecks.
  • specs/performance_profiler.t27: parses and typechecks.
  • specs/topology_visualizer.t27: parses and typechecks.
  • specs/traffic_animator.t27: parses and typechecks.

Read by the model

This PR fixes Rust compilation errors in 10 generated modules by updating their .t27 specs (mutable value parameters → local var copies; array repeat count literal; redundant u32 >= 0 checks removed; constant renamed to SCREAMING_SNAKE_CASE). It regenerates all three targets (Rust, C, Zig) and adds a compile gate (tests/gen_rust_corpus_compiles.rs) that builds all 102 gen/rust/*.rs files as separate crates with -D warnings, plus a behavior test (tests/gen_rust_value_params.rs) for the changed functions.

Worth a look

  • gen/rust/api_documenter.rs:278 — let empty_params: [u32; MAX_PARAMETERS as usize] = [0; 16]; initializes only 16 elements. If MAX_PARAMETERS != 16 this leaves the rest uninitialized (UB in Rust). The C side uses t27_arr_uint32_t_16 and the spec likely defines 16, but the type ascription [u32; MAX_PARAMETERS as usize] should match the initializer length.
  • gen/rust/auto_config.rs:352 — config[((index as usize)) as usize] has a redundant double cast; harmless but odd.
  • gen/rust/auto_config.rs:112–127 — discover_network_params reformats the array literal; verify the element count still matches MAX_PARAMS (16).
  • tests/gen_rust_corpus_compiles.rs — The test compiles each module as a separate crate with allow(clippy::all, unused). This may hide real issues (e.g., dead code, clippy lints) that would surface in the main workspace build. The gate only proves -D warnings passes under those allows.
  • gen/c/auto_config.c:210–238 — validate_config drops value >= 0 checks on u32. Correct (always true), but ensure no callers relied on the side-effect of the comparison (none in the diff).

Read: 43 files, +1313 -429, the whole diff up to 60000 characters (the rest was not read). Head 59f39b6. Model: openai-compatible/nvidia/nemotron-3-ultra-550b-a55b. Commands: @t27-bees review | summary | help | pause | resume. Free for every repository.

@dmitrii-f-t27

Copy link
Copy Markdown
Contributor Author

@gHashTag, please merge #409 and then #411. Both are from my fork; I cannot merge in gHashTag/tri-net. State at 2026-10-11 15:45Z: both are MERGEABLE / CLEAN against main d6deeb39, and all 4 checks pass on each head.

Order PR Head Closes Checks
1 #409 59f39b68 #399 build + test, Icarus KATs, drift, GitGuardian: pass (run 38092901680)
2 #411 da49268a #410 build + test with tests/gen_rust_bounds.rs 5/5, Icarus KATs, drift, GitGuardian: pass (run 38150829272)

#411 is stacked on #409 because both change the same three specs. Until #409 merges, the #411 diff also shows the #409 commit.

#411 fixes the out-of-bounds indexing and the division by zero in inject_fault, update_animation_packets, calculate_circular_layout and calculate_hierarchical_layout. The change is in the .t27 specs, and gen/ is regenerated with the pinned t27c. Three more hazards of the same class are in #412.

Dmitrii Fedorov (@dmitrii-f-t27)

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.

Restore remaining generated Rust corpus: 89/102 compile, parameter mutations and type defects

1 participant