Skip to content

docs(book): put the book's Rust blocks on rustfmt's import order - #1241

Merged
nihalpasham merged 3 commits into
NVIDIA:mainfrom
vyncint:docs/book-blocks-rustfmt-import-order
Sep 6, 2026
Merged

nihalpasham merged 3 commits into
NVIDIA:mainfrom
vyncint:docs/book-blocks-rustfmt-import-order

Conversation

@vyncint

@vyncint vyncint commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Closes #1240. This is the follow-up invited in the #1193 review.

#1193 made cargo oxide new emit rustfmt-clean projects. The book's hand-written blocks kept the old import order, so a reader who copies one into a project gets the same diff on the same first cargo oxide fmt --check.

Scope, measured

Over every tracked book page, taking each ```rust block that contains a cuda_* import and running the pinned rustfmt at the book's edition:

blocks
already rustfmt-clean 58
differ in imports only — fixed here 15
differ in other formatting — left alone 23

After the change: 73 clean, 0 differing in imports, and the same 23 differing in other formatting as before.

The 15 are the two orderings #1193 fixed in the templates: crates not sorted (cuda_device/cuda_host ahead of cuda_core, and cuda_async where present), and DisjointSlice and friends after the lowercase items inside the braces instead of before them under style edition 2024.

What is deliberately not touched

The 23 differ for reasons unrelated to imports — one parameter per line in a function signature, { /* ... */ } split across two lines, a wrapped call collapsed. Reformatting deliberately laid-out teaching code is a different change with a different argument, so those blocks are byte-identical here.

Only rustfmt's import region is spliced back into each block, not its whole formatted output. That distinction is load-bearing: taking the whole block reflows the teaching code above, and I only found that out by diffing rather than trusting my own classifier. Verified afterwards by grepping the resulting diff for anything that is not a use statement or one of its continuation lines — nothing.

A correction I owe on my own issue

The scope figures in #1240 as originally filed were wrong: it said 38 blocks and claimed every diff was imports-only. My measurement filtered rustfmt's --check output with startswith("-"), but that output is colourised, so every changed line begins with an ANSI escape, nothing matched, and the "is every changed line an import?" test was vacuously true. 38 was really "blocks that differ from rustfmt for any reason". Re-measured with --color=never, corrected on the issue, and the table above is the corrected version.

Why nothing catches this

A markdown code block is compiled by nothing and formatted by nothing. scripts/check-book-api-names.sh verifies that the device-API names the docs show exist, which is a different property and passes today, before and after.

Test plan

  • sphinx-build -W --keep-going -b html cuda-oxide-book — build succeeded.
  • scripts/check-book-api-names.sh, scripts/check-book-catalog-stamp.sh, scripts/check-spdx-headers.sh — pass.
  • Re-ran the block measurement on the result: 0 blocks differ from rustfmt in imports.
  • Confirmed the diff touches only cuda-oxide-book/ and only import lines.
  • No device code, so there is no GPU evidence to attach.

NVIDIA#1193 made `cargo oxide new` emit rustfmt-clean projects, because a scaffolded
project failing its own first `cargo oxide fmt --check` is a bad first five
minutes. The book's hand-written blocks kept the old order, so a reader who
copies one into a project gets the same diff on the same command.

Measured over every tracked book page, taking each ```rust block that contains
a `cuda_*` import and running the pinned rustfmt at the book's edition:

    already rustfmt-clean                            58
    differ in imports only         <- fixed here     15
    differ in other formatting     <- left alone     23

The 15 are the same two orderings NVIDIA#1193 fixed in the templates: crates not
sorted (`cuda_device`/`cuda_host` ahead of `cuda_core`, and `cuda_async` where
present), and `DisjointSlice` and friends after the lowercase items inside the
braces rather than before them under style edition 2024.

The 23 differ for reasons that have nothing to do with imports -- one
parameter per line in a function signature, `{ /* ... */ }` split across two
lines, a wrapped call collapsed. Reformatting deliberately laid-out teaching
code is a different change with a different argument, so those blocks are
untouched.

Only rustfmt's import region is spliced back into each block, not its whole
formatted output, so every non-import line stays byte-identical. Taking the
whole block instead reflows that teaching code, which is what made the
distinction worth drawing rather than assuming.

Nothing catches this today: a markdown code block is compiled by nothing and
formatted by nothing, and `check-book-api-names.sh` verifies that the device-API
names the docs show exist, which is a different property and already passes.

Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
@nihalpasham nihalpasham added documentation Improvements or additions to documentation QoL-improvement Quality-of-life improvement; not a correctness fix labels Sep 6, 2026
The first commit put 17 Rust blocks in 14 book pages on rustfmt's
edition-2024 import order. 30 blocks in 12 pages still carried the old
order (crates unsorted, uppercase names after lowercase ones). This
splices rustfmt's output for the top-level `use` region into each of
them, the same mechanism the first commit used: 16 whole-item blocks
and 14 partial snippets whose `use` lines format on their own. Every
changed line is a `use` statement or a brace-list continuation; no
other line moved, so the one-param-per-line teaching layout stays.

Also adds the `DisjointSlice` import the `reduce_dynamic` block in the
shared-memory chapter used without importing, then formats that region.

With both commits the book has one import order: 47 blocks in 18 pages
changed, 0 blocks differ from `rustfmt --edition 2024` in their imports.

Signed-off-by: nihalpasham <nihalp@nvidia.com>
A markdown block is compiled by nothing and formatted by nothing, which
is how 47 blocks drifted from the order `cargo fmt` writes in an
edition-2024 `cargo oxide new` project after the scaffold templates
were fixed with a real-rustfmt test.

scripts/check-book-import-order.sh walks every tracked ```rust block
under cuda-oxide-book/, extracts each contiguous run of top-level `use`
items, and runs `rustfmt --edition 2024 --check` on that region alone.
It prints the page, the fence line and rustfmt's diff, and exits
non-zero. Signatures, bodies and comments are never formatted, so
teaching layout and partial snippets with no enclosing item cannot
trip it. A `use` line rustfmt cannot parse is reported too. Parse
self-test: at least 50 blocks with imports must be found.

rustfmt comes from rust-toolchain.toml through the rustup proxy, as in
fmt.yml, so the pinned nightly's order is the one checked.

On the branch before the sweep the guard listed all 30 stale blocks in
12 pages; after it, 98 import regions in 98 blocks across 42 pages pass.
Wired into status-guard.yml as `book-import-order` and into the
Justfile's `check-guards` recipe, which mirrors that workflow.

Signed-off-by: nihalpasham <nihalp@nvidia.com>
@nihalpasham
nihalpasham merged commit 59b57d6 into NVIDIA:main Sep 6, 2026
54 checks passed
@nihalpasham

Copy link
Copy Markdown
Collaborator

The splice mechanism is right and kept: rustfmt's import region back into the block, nothing else moved. After your commit, 30 blocks still carried the old order, including the landing block in index.md.

                blocks  pages
your commit       17     14
stacked here      31     13   (one page shared)
book now          47     18   -> 0 blocks differ from rustfmt in imports

What we stacked on your branch (your commit untouched underneath)

  • 627150a: the 30 remaining blocks (16 whole-item, 14 partial snippets whose use lines parse on their own) plus the missing DisjointSlice import in the reduce_dynamic block; every changed line is a use or a brace-list continuation
  • 714d0bd: scripts/check-book-import-order.sh and a status-guard job, the pinned rustfmt --edition 2024 --check over each block's import region. Fails on your head (lists the 30), passes now. Same idea as the cargo-oxide: make cargo oxide new emit rustfmt-clean projects #1193 test: the real rustfmt decides, nobody re-derives its rules.

Validation: book builds under sphinx-build -W, all status guards pass. Merged, and with the full sweep "Closes #1240" holds. One correction to the body for the record: 17 blocks in 14 files, and "58 clean" is 9 rustfmt-clean plus 49 blocks rustfmt cannot parse whole.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation QoL-improvement Quality-of-life improvement; not a correctness fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Book Rust blocks still use the pre-#1193 import order, so copying one fails cargo oxide fmt --check

2 participants