[BUG] Private-item API exports lose named-struct opacity #7

Closed
opened 2026-09-14 09:55:22 +02:00 by erikinkinen · 0 comments
Owner

Summary

The Rustdoc API renderer omits the opaque-field marker from named structs when JSON includes private field items with has_stripped_fields: false. It correctly hides the field details, but then displays an incomplete public field list as though users could construct that struct directly.

Reproduction

Using the renderer at Docs 7ccbe0bfa83ce5942878fb7cf8c57bb1abe75d00, generate the IPC reference from original Lib-ipc de6892790de69f40f749c393d24078b287b36175 with Rustdoc JSON format 54 and --document-private-items. Comparison against the accepted public API reference finds eleven changed opaque-struct declarations even though those Rust types did not change.

The added deterministic format 54 regression runs with python3 -m unittest discover -s tests -p test_generate_library_api_reference.py -k test_unstripped_named_fields_preserve_opaque_construction -v. Against the original renderer it reports one test with three failed subcases: all-private named fields, mixed public/private named fields and an unavailable field record. This command includes the new regression fixture; it is not an unchanged-checkout test name.

Expected and actual behavior

Named structs with any inaccessible field must retain one /* private fields */ marker while preserving visible declaration order. Private field names and types must remain undisclosed. Private-item and stripped-field exports must describe the same public construction boundary.

Actual examples: UnknownIpcResultCodeV1 and several iterator wrappers render as empty named structs, and mixed records lose their final opaque marker. The first real regenerated-reference comparison rejects all eleven differences. The original deterministic regression exits 1 with three assertion failures.

Environment and identity

  • Docs base: 7ccbe0bfa83ce5942878fb7cf8c57bb1abe75d00, feature/posix-compat.
  • IPC producer: original signed de6892790de69f40f749c393d24078b287b36175; no changed opaque Rust types or replacement source objects.
  • Rustdoc JSON format 54 from the explicit nightly toolchain, exported with private items; native Python unit tests and Pandoc rendering on Linux.
  • No guest VM, device authority, runtime capability change or private field disclosure is claimed. The defect concerns public documentation accuracy.

Evidence and prior checks

The accepted reference, rejected comparison and original failing regression remain recorded. Existing tests already cover stripped named fields and unstripped private tuple fields; the missing case is a supplied private named field when Rustdoc does not set its stripped-fields flag.

The correction records hidden named fields while scanning and emits one opaque marker without exposing their names or types. Preserve all earlier signatures and routes when regenerating the two IPC references. The local checks recorded below pass; the corrected signed revision's own CI now also passes as recorded below.

Tracking

Current signed Docs 28b44183368c512da9c5b804f570ff497ae3b6fc passes push CI 839 and PR CI 840, completed by 08:14:56 UTC on September 14. Four complete logs total 752,154 bytes and correlate with the original workflow and build scripts. Each manual job passes 45 tests and finishes at 2,339 pages with zero final warnings; thirty first-pass and one second-pass convergence warnings resolve. Both Markdown jobs check 55 files with zero errors. CI logs report a 4,111,798-byte PDF; its artifact bytes and geometry were not independently inspected. The separate local full-PDF and five-page visual review passes. This closes renderer issue #7 only; native VM, realm producer, full audits and guest self-hosting remain open.

Signed Docs 28b44183368c512da9c5b804f570ff497ae3b6fc documents native local lifetime revocation and corrects the opaque named-field renderer (#7). Fresh original-source IPC/shim references preserve every old signature and add only the syscall assignment and safe wrapper. All 45 Docs tests, both generation checks, 55 Markdown files, canonical governance/headings/links and the 150-issue index pass. The full 2,339-page manual builds in 165.44 seconds with zero final warnings; all 426,181 word boxes fit and five selected pages pass visual review. Push CI 839 and PR CI 840 both pass as recorded above. Native VM, realm producer, complete audits and both full build generations inside EriX remain open.

  • Documentation audit: #2; complete inline/API documentation: #1; implementation and manual validation: #4.
  • The native lifetime rollout is tracked in Kernel issue 7; this renderer correction does not establish native acceptance or guest self-hosting.
## Summary The Rustdoc API renderer omits the opaque-field marker from named structs when JSON includes private field items with `has_stripped_fields: false`. It correctly hides the field details, but then displays an incomplete public field list as though users could construct that struct directly. ## Reproduction Using the renderer at Docs `7ccbe0bfa83ce5942878fb7cf8c57bb1abe75d00`, generate the IPC reference from original Lib-ipc `de6892790de69f40f749c393d24078b287b36175` with Rustdoc JSON format 54 and `--document-private-items`. Comparison against the accepted public API reference finds eleven changed opaque-struct declarations even though those Rust types did not change. The added deterministic format 54 regression runs with `python3 -m unittest discover -s tests -p test_generate_library_api_reference.py -k test_unstripped_named_fields_preserve_opaque_construction -v`. Against the original renderer it reports one test with three failed subcases: all-private named fields, mixed public/private named fields and an unavailable field record. This command includes the new regression fixture; it is not an unchanged-checkout test name. ## Expected and actual behavior Named structs with any inaccessible field must retain one `/* private fields */` marker while preserving visible declaration order. Private field names and types must remain undisclosed. Private-item and stripped-field exports must describe the same public construction boundary. Actual examples: `UnknownIpcResultCodeV1` and several iterator wrappers render as empty named structs, and mixed records lose their final opaque marker. The first real regenerated-reference comparison rejects all eleven differences. The original deterministic regression exits 1 with three assertion failures. ## Environment and identity - Docs base: `7ccbe0bfa83ce5942878fb7cf8c57bb1abe75d00`, `feature/posix-compat`. - IPC producer: original signed `de6892790de69f40f749c393d24078b287b36175`; no changed opaque Rust types or replacement source objects. - Rustdoc JSON format 54 from the explicit nightly toolchain, exported with private items; native Python unit tests and Pandoc rendering on Linux. - No guest VM, device authority, runtime capability change or private field disclosure is claimed. The defect concerns public documentation accuracy. ## Evidence and prior checks The accepted reference, rejected comparison and original failing regression remain recorded. Existing tests already cover stripped named fields and unstripped private tuple fields; the missing case is a supplied private named field when Rustdoc does not set its stripped-fields flag. The correction records hidden named fields while scanning and emits one opaque marker without exposing their names or types. Preserve all earlier signatures and routes when regenerating the two IPC references. The local checks recorded below pass; the corrected signed revision's own CI now also passes as recorded below. ## Tracking Current signed Docs `28b44183368c512da9c5b804f570ff497ae3b6fc` passes [push CI 839](https://git.erikinkinen.fi/erix/docs/actions/runs/839) and [PR CI 840](https://git.erikinkinen.fi/erix/docs/actions/runs/840), completed by 08:14:56 UTC on September 14. Four complete logs total 752,154 bytes and correlate with the original workflow and build scripts. Each manual job passes 45 tests and finishes at 2,339 pages with zero final warnings; thirty first-pass and one second-pass convergence warnings resolve. Both Markdown jobs check 55 files with zero errors. CI logs report a 4,111,798-byte PDF; its artifact bytes and geometry were not independently inspected. The separate local full-PDF and five-page visual review passes. This closes renderer issue #7 only; native VM, realm producer, full audits and guest self-hosting remain open. Signed Docs `28b44183368c512da9c5b804f570ff497ae3b6fc` documents native local lifetime revocation and corrects the opaque named-field renderer (#7). Fresh original-source IPC/shim references preserve every old signature and add only the syscall assignment and safe wrapper. All 45 Docs tests, both generation checks, 55 Markdown files, canonical governance/headings/links and the 150-issue index pass. The full 2,339-page manual builds in 165.44 seconds with zero final warnings; all 426,181 word boxes fit and five selected pages pass visual review. [Push CI 839](https://git.erikinkinen.fi/erix/docs/actions/runs/839) and [PR CI 840](https://git.erikinkinen.fi/erix/docs/actions/runs/840) both pass as recorded above. Native VM, realm producer, complete audits and both full build generations inside EriX remain open. - Documentation audit: #2; complete inline/API documentation: #1; implementation and manual validation: #4. - The native lifetime rollout is tracked in [Kernel issue 7](https://git.erikinkinen.fi/erix/kernel/issues/7); this renderer correction does not establish native acceptance or guest self-hosting.
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#7
No description provided.