Repository navigation
Phase 3 — const/macro examples, domain starters, quality signals, AI aids (completes the roadmap) - #20
Merged
Conversation
Phase 3 const/macro items from docs/roadmap-production-ready.md. - crates/core-tests/examples/const_eval_walkthrough.rs (new): const fns (factorial, fibonacci), the const-testing primitive 'const _: () = assert!(...)' — a broken const fn fails the BUILD (E0080), checked by every --all-targets build including CI's clippy — the same values consumed in a const context (a table whose length IS a const fn's output), and runtime #[test]s pinning them. - syntax-tests gains parse_cases!: a macro_rules! case-table expander (one #[test] per row) with a fallback arm emitting a helpful compile_error! instead of the classic "no rules expected" wall, plus four macro-generated cases and a ui/fail/macro_case_missing_arrow.rs trybuild fixture — its expected diagnostic is OUR message text, stable across rustc versions, unlike the rendered errors the existing type-mismatch fixtures assert on. No new CI job: the compile-fail job's glob picks the fixture up. - docs/adding-tests.md gains a "Compile-time and macro-powered checks" section; examples/README.md lists the new walkthrough. Verified against real execution: the example runs and its 3 runtime tests pass; a deliberately wrong static assertion was confirmed to fail the build with 'E0080: evaluation panicked: assertion failed: factorial(5) == 121' (scratch crate); the trybuild fixture passes with the committed .stderr (7 unit tests, 1 compile-fail); fmt/clippy clean, 64 tests pass across the full feature set. One compile error caught pre-commit: a 'use crate::parse_cases;' inside lib.rs is redundant (unused-import) — #[macro_export] macros are in textual scope after their definition; only external crates need the import.
Phase 3 domain-starter items from docs/roadmap-production-ready.md:
three self-contained example crates showing the template's test shapes
in real domains, each detached with an empty [workspace] table (the
fuzz/ pattern) so the default 'cargo test --workspace' stays fast and
dependency-light.
- examples/parser-starter/: arithmetic-expression evaluator — unit
tests per construct (precedence, parens, unary minus, every error
variant), proptest property tests (arbitrary strings never panic;
generated operand pairs round-trip through format→parse→eval), and a
total EvalError enum (no panics anywhere).
- examples/async-service-starter/: tokio key-value store —
#[tokio::test(start_paused = true)] for deterministic expiry tests,
concurrent inserts through a shared Arc<Mutex> store, and a
background sweeper task with graceful shutdown.
- examples/cli-starter/: wc-style counting CLI — pure logic in the lib
(unit-tested), thin main (I/O wiring only), integration tests
spawning the real binary via env!("CARGO_BIN_EXE_tally") asserting
stdout/stderr/exit codes, and --json machine-readable output.
- docs/domain-starters.md (new): the containment pattern, what each
starter demonstrates, and how to copy one out. examples/README.md
lists them.
Verified against real execution: parser 8 unit + 3 property + 1
doc-test; async-service 5 tests; cli 7 unit + 7 integration + a live
binary run — all green. Main workspace unaffected (45 tests, default
features). Three bugs caught pre-commit: Option::is_none_or is Rust
1.82 (the starters declare MSRV 1.75 — replaced with a match), a
paused-time ordering bug in the sweeper test (the task must register
its timer before time advances), and Copy derived on a struct holding
a String.
Phase 3 quality-signal items from docs/roadmap-production-ready.md — local recipes only, no CI gates, consistent with the template's informational stance for everything beyond correctness. - just bloat / just bloat-json (cargo-bloat): code-size analysis per function/crate, table or JSON (bloat.json joins the Phase 1.3 machine-readable outputs). Both variadic so callers pass --bin/ --release/etc. - just size: release-builds the template's example binary (the workspace itself is lib-only) and reports sizes; documents comparing your own target/release/<bin> across commits in an adopted workspace. - just timings: cargo's built-in compile-time report — verified it writes target/cargo-timings/cargo-timing-*.html. - README 'Coverage, Reporting, and Debugging' gains an 'Optional quality signals' bullet; docs/machine-readable-outputs.md lists bloat-json; .gitignore covers bloat.json. Verified against real execution: cargo bloat --bin tally --message-format json emits valid JSON (file/text-section sizes plus per-function breakdown); the timings report is generated by cargo build --release --workspace --timings.
…Phase 3d) Phase 3 doc items from docs/roadmap-production-ready.md — the last Phase 3 items, completing the exit criteria. - docs/ai-test-generation.md (new): the checklist every generated test must satisfy (right category, right shape, no new default deps, MSRV 1.75, docs, determinism — mirroring the CONTRIBUTING process), plus fill-in templates for the common generation targets: signature→property derivation (totality, round-trip, invariance, boundary — in priority order), trybuild compile-fail (prefer compile_error! text over rendered rustc diagnostics), assert_debug_snapshot, golden-case tables, and mechanical category/fixture placement rules. Points at the evaluation harness for reviewing generated implementations, and the differential helpers for proving equivalence against a reference. - docs/adoption.md: new 'Minimal adoption' section — the smallest useful signal (Cargo.toml with the inheritance tables + core-tests + syntax-tests, default features, zero heavy deps), growing one dependency-pulling category at a time, and the one thing never to trim (the workspace.package/lints tables). - docs/adding-tests.md: new 'When to promote a template test into the real library's tests' — promote by moving not copying, keep feature flags honest; plus an intro pointer to ai-test-generation.md. Final Phase 3 verification (all green): fmt clean; clippy -D warnings clean across all features; 64 tests pass in the full suite; compile-fail job green; all three starters 0 failures.
…MSRV doc-test Two failures PR #20's CI run caught, both from Phase 2/3 additions and both invisible to local verification on modern stable: - 'cargo generate' aborted with 'Substitution skipped, found invalid syntax' on examples/cli-starter/src/lib.rs — its JSON renderer's format!("{{{}}}...") is valid Rust but invalid liquid (a {{ tag with no name), breaking the adoption job. Added to cargo-generate.toml's [template] exclude, together with target/** and examples/*/target/**: cargo-generate skips CACHEDIR.TAG dirs but not .gitignore, so a dirty working tree fed binary target/debug/.fingerprint/* files through the same parser (local 'just adopt-test' hit this; CI's clean checkout didn't). - The parse_cases! doc example failed the msrv job under Rust 1.75 (E0601: no main function): 1.75's rustdoc decides whether to wrap a doctest in fn main() by textually scanning for one, and the example's "fn main() {}" string literals made it skip the wrapper. Newer rustdoc parses properly, so stable passed. The example now carries an explicit fn main wrapper, with a comment on why. Verified locally against the exact CI conditions: 'cargo +1.75 test --workspace --exclude performance-tests' (the msrv job's command, lockfile deleted first per that job's procedure) exits 0 with doc-tests green; './scripts/adoption-check.sh' passes end-to-end including the generated tree's doc-tests; fmt clean, 64 tests pass, compile-fail green.
The previous fix commit's own changelog entry reintroduced the exact bug
it documented: quoting format!("{{{}}}...") in prose is a {{{...}}} run
— invalid liquid — which aborted cargo generate on CHANGELOG.md in CI's
adoption job (the file my own entry had just taught readers about).
Changelogs are documentation and are never templated, so exclude the
whole file: this project's history legitimately discusses {{...}}
syntax repeatedly (the justfile's {{target}}, GitHub's
${{ ... }} expressions), and while *valid* liquid passes through
unchanged (verified: the generated docs keep ${{ github.base_ref }}
intact), any future entry quoting doubled braces would abort generation
the same way.
Verified: cargo generate exits 0 and copies CHANGELOG.md verbatim;
the full adoption script (both legs + eval harness) passes end-to-end.
The Unreleased section (Phases 2 and 3 — evaluation harness, differential helpers, mutation polish, const/macro examples, domain starters, quality signals, AI aids, plus the CI fixes) becomes [1.1.0] - 2026-10-14, with a fresh empty Unreleased above it. Cutting it here so the release tag lands with the changelog already complete.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phases 3a–3d of
docs/roadmap-production-ready.md— the final phase. With this, the roadmap is complete.What's in it
3a — const/macro testing examples.
crates/core-tests/examples/const_eval_walkthrough.rs: const fns plusconst _: () = assert!(...)static assertions — a broken const fn fails the build (verified:E0080: evaluation panicked: assertion failed), checked by every--all-targetsbuild including CI's clippy.syntax-testsgainsparse_cases!, amacro_rules!case-table expander with a fallback arm emitting a helpfulcompile_error!, plus a trybuild fixture whose expected diagnostic is our own message text — stable across rustc versions.3b — Domain starter examples.
examples/parser-starter/(arithmetic evaluator: unit tests per construct, proptest panic-freedom/round-trips, total error enum),examples/async-service-starter/(tokio key-value store: paused-time expiry tests, concurrent inserts, background sweeper with graceful shutdown), andexamples/cli-starter/(wc-style CLI: pure logic in the lib, thinmain, integration tests spawning the real binary,--jsonoutput) — each a detached standalone workspace, documented indocs/domain-starters.md.3c — Quality signals (opt-in, informational).
just bloat/bloat-json(cargo-bloat, JSON included in the machine-readable outputs),just size(binary-size tracking),just timings(cargo's built-in compile-time report). Local recipes only — no CI gates.3d — Docs.
docs/ai-test-generation.md: the checklist every generated test must satisfy plus fill-in templates (signature→property derivation, trybuild, snapshot, golden tables, placement rules) — aimed at LLM-assisted test generation.docs/adoption.mdgains a "Minimal adoption" section;docs/adding-tests.mdgains "When to promote a template test into the real library's tests".Notes
-D warningsclean across all features; 64 tests pass in the full suite; compile-fail green; all three starters 0 failures.Option::is_none_oris Rust 1.82 against the declared MSRV 1.75; a paused-time ordering bug in the sweeper test (the task must register its timer before time advances);Copyderived on a struct holding aString; two byte-count miscalculations in golden expectations.Context
Phases 1 and 2 are already merged (#17, #19), so this PR's diff is Phase 3 only — the final phase of the roadmap. The branch is stacked on the merged work, so there are no conflicts.