[BUG] Generated API references misrepresent declaration shapes and field visibility #5

Open
opened 2026-09-12 12:32:55 +02:00 by erikinkinen · 0 comments
Owner

Summary

The manual's public API renderer infers declaration shape from visible field text. This turns opaque tuple wrappers into apparent public unit constructors and named opaque structs into tuple structs. Tuple enum variants can also acquire invalid numeric named fields, and public struct fields omit their required pub access marker. The defect misstates the documented Rust API; it does not change compiled Rust behavior.

Reproduction

At docs commit d91ddf63bc502c51da7c8e1eb12ba8ecff723357, inspect the generated lib_ipc::SignalIdentityV1 declaration in manual/8-libraries/api-reference/lib-ipc.tex: it reads pub struct SignalIdentityV1;.

The recorded source is lib-ipc 832cc9096e3da50f29c501f47de8d41f23fa55f0, whose src/signals.rs:71 defines pub struct SignalIdentityV1(u32);. Its retained Rustdoc format-54 item has "kind": {"tuple": [null]} because the field is private. Rendering that item deterministically produces the incorrect unit declaration. The published lib-block reference renders lib_block::Error::Transport as Transport { 0: u32 }, and lib-cli renders lib_cli::NumericError::InvalidDigit as InvalidDigit { 0: usize }. Separate minimal format-54 tuple-variant fixtures with inherited field visibility and positional name "0" reproduce this wrong punctuation.

Expected and actual behavior

The renderer should preserve explicit unit, tuple and named shapes, field order and visibility. Stripped private fields require unmistakable placeholders without their private types; named opaque structs require braces. Tuple positions must not become named Rust fields. Public struct fields retain pub, while inherited enum fields and private placeholders do not receive it.

Actual output discards stripped tuple positions and guesses punctuation from the remaining strings. The initial independent shape regression fails on opaque, mixed, public tuple and empty named/tuple fixtures; the variant regression separately fails on numeric positional names. A separate visibility fixture fails when pub is absent on mixed or fully public struct fields. Existing test success did not cover these cases.

Environment and identity

  • Documentation repository: d91ddf63bc502c51da7c8e1eb12ba8ecff723357.
  • Published generator SHA-256: fa15b9782f2590b5aac6c4f7df3f637257a1e885496aab7e91f74e5ada7358fa.
  • Recorded lib-ipc source: 832cc9096e3da50f29c501f47de8d41f23fa55f0; retained Rustdoc JSON SHA-256: 8bdffea8eb3c6c5a8c3e96c6d6aa39518e4d863165ae9ddca77a9f783fa16820.
  • Input is public Rustdoc format 54 with private-item collection disabled. No image, VM, runtime capability route or process authority is involved.
  • Last known working renderer revision is unknown. Historical JSON digest matching proves correspondence to the recorded generated snapshot, not a fresh source/toolchain rebuild of every historical crate.

Evidence and prior checks

The published false declaration and its source are directly inspectable at the generated reference and the original Rust definition.

The retained original JSON digests match all 33 existing generated-reference headers. A shape-aware candidate preserves all historical route sets; its declaration changes are confined to struct/enum shape rendering and public struct-field visibility. Independent fixtures cover unit, empty tuple/named, opaque tuple/named, mixed public/private fields, field order and enum discriminants. The corrected full manual passes its strict warning gate: 2,027 pages, 389,257 word boxes within page bounds and no final warnings. Nine selected pages were visually inspected. The correction is published in signed commit c8e754bff3 and WIP PR #4. Current-revision CI remains separately tracked.

Tracking

Track the renderer correction and matching generated-reference refresh in the documentation repository. Acceptance requires focused red/green regressions, unchanged source labels and retained JSON hashes for historical rows, generator check-mode agreement, and a complete warning-free manual build. Fresh source/toolchain regeneration of unrelated historical snapshots remains separate audit work.

## Summary The manual's public API renderer infers declaration shape from visible field text. This turns opaque tuple wrappers into apparent public unit constructors and named opaque structs into tuple structs. Tuple enum variants can also acquire invalid numeric named fields, and public struct fields omit their required `pub` access marker. The defect misstates the documented Rust API; it does not change compiled Rust behavior. ## Reproduction At docs commit `d91ddf63bc502c51da7c8e1eb12ba8ecff723357`, inspect the generated `lib_ipc::SignalIdentityV1` declaration in `manual/8-libraries/api-reference/lib-ipc.tex`: it reads `pub struct SignalIdentityV1;`. The recorded source is lib-ipc `832cc9096e3da50f29c501f47de8d41f23fa55f0`, whose `src/signals.rs:71` defines `pub struct SignalIdentityV1(u32);`. Its retained Rustdoc format-54 item has `"kind": {"tuple": [null]}` because the field is private. Rendering that item deterministically produces the incorrect unit declaration. The published lib-block reference renders `lib_block::Error::Transport` as `Transport { 0: u32 }`, and lib-cli renders `lib_cli::NumericError::InvalidDigit` as `InvalidDigit { 0: usize }`. Separate minimal format-54 tuple-variant fixtures with inherited field visibility and positional name `"0"` reproduce this wrong punctuation. ## Expected and actual behavior The renderer should preserve explicit unit, tuple and named shapes, field order and visibility. Stripped private fields require unmistakable placeholders without their private types; named opaque structs require braces. Tuple positions must not become named Rust fields. Public struct fields retain `pub`, while inherited enum fields and private placeholders do not receive it. Actual output discards stripped tuple positions and guesses punctuation from the remaining strings. The initial independent shape regression fails on opaque, mixed, public tuple and empty named/tuple fixtures; the variant regression separately fails on numeric positional names. A separate visibility fixture fails when `pub` is absent on mixed or fully public struct fields. Existing test success did not cover these cases. ## Environment and identity - Documentation repository: `d91ddf63bc502c51da7c8e1eb12ba8ecff723357`. - Published generator SHA-256: `fa15b9782f2590b5aac6c4f7df3f637257a1e885496aab7e91f74e5ada7358fa`. - Recorded lib-ipc source: `832cc9096e3da50f29c501f47de8d41f23fa55f0`; retained Rustdoc JSON SHA-256: `8bdffea8eb3c6c5a8c3e96c6d6aa39518e4d863165ae9ddca77a9f783fa16820`. - Input is public Rustdoc format 54 with private-item collection disabled. No image, VM, runtime capability route or process authority is involved. - Last known working renderer revision is unknown. Historical JSON digest matching proves correspondence to the recorded generated snapshot, not a fresh source/toolchain rebuild of every historical crate. ## Evidence and prior checks The published false declaration and its source are directly inspectable at [the generated reference](https://git.erikinkinen.fi/erix/docs/src/commit/d91ddf63bc502c51da7c8e1eb12ba8ecff723357/manual/8-libraries/api-reference/lib-ipc.tex) and [the original Rust definition](https://git.erikinkinen.fi/erix/lib-ipc/src/commit/832cc9096e3da50f29c501f47de8d41f23fa55f0/src/signals.rs). The retained original JSON digests match all 33 existing generated-reference headers. A shape-aware candidate preserves all historical route sets; its declaration changes are confined to struct/enum shape rendering and public struct-field visibility. Independent fixtures cover unit, empty tuple/named, opaque tuple/named, mixed public/private fields, field order and enum discriminants. The corrected full manual passes its strict warning gate: 2,027 pages, 389,257 word boxes within page bounds and no final warnings. Nine selected pages were visually inspected. The correction is published in signed commit c8e754bff357861bad0902b32891093722496f26 and [WIP PR #4](https://git.erikinkinen.fi/erix/docs/pulls/4). Current-revision CI remains separately tracked. ## Tracking Track the renderer correction and matching generated-reference refresh in the documentation repository. Acceptance requires focused red/green regressions, unchanged source labels and retained JSON hashes for historical rows, generator check-mode agreement, and a complete warning-free manual build. Fresh source/toolchain regeneration of unrelated historical snapshots remains separate audit work.
erikinkinen changed title from [BUG] Generated API references misrepresent opaque structs and tuple variants to [BUG] Generated API references misrepresent declaration shapes and field visibility 2026-09-12 12:55:31 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
erix/docs#5
No description provided.