Rust chapter (updated version)#128
Merged
Merged
Conversation
|
Closed
GrosQuildu
marked this pull request as ready for review
May 13, 2026 12:53
elopez
approved these changes
Jul 2, 2026
feature(strict_provenance) was stabilized in Rust 1.84 and the gate removed; on current nightly it warns and is a functional no-op, so the lossy/fuzzy_provenance_casts lints the command intends to enable never fire. The correct gate is feature(strict_provenance_lints).
The second proptest example uses `use proptest_derive::Arbitrary;` and `#[derive(Arbitrary)]`, but the dev-dependencies block only listed `proptest`. As written the example fails with E0432: unresolved import `proptest_derive`. proptest-derive is a separate crate.
Updated the pinned proptest version from 1.5.0 to the current 1.11.0 (with proptest-derive 0.8.0). Confirmed both proptest examples in this section compile and pass under these versions.
cargo vendor only copies dependencies into a local directory; it silently vendors a crate pulled from multiple sources (e.g. crates.io + git) with no warning or report. cargo-deny's sources check is the tool that actually reports such deps. Replace the incorrect cargo vendor guidance accordingly.
grcov's --branch flag produces no branch data on the stable toolchain the example pins (Dockerfile rust:1.95.0): LLVM source-based branch coverage requires nightly with -Zcoverage-options=branch. Verified the shipped grcov LCOV artifacts contain BRF:0/BRH:0 and zero BRDA records, and reproduced 0 branches on stable vs 10 on nightly. - Note the nightly requirement under the coverage-tool comparison table. - Drop the dead --branch flags from get_coverage.sh's stable grcov pipeline.
The overview claimed the compiler guarantees no UB or data race for all Rust programs 'no matter the inputs'. That is false for unsound unsafe code and contradicts the same page (unsafe UB, unsound safe Rust) and its own diagram. Verified with a compiler-accepted program that is memory-safe for one input and UB (out-of-bounds read) for another, confirmed by Miri: 'Undefined Behavior' on the OOB input, clean on the safe input.
OsStr was listed as a UTF-8/bytes conversion that 'just returns the bytes'. It is neither: OsStr holds platform-native strings that may not be valid UTF-8, and it has no portable raw-bytes accessor (as_bytes is Unix-only; as_encoded_bytes uses a non-portable encoding). Verified: bare OsStr has no .as_bytes() (E0599), the method requires the Unix-only OsStrExt trait, and an OsStr can hold non-UTF-8 bytes where to_str() returns None. Also corrected the from_utf8_lossy description (replaces invalid sequences, not per-byte).
URLs were /docs/languages/rust/lang-rust-static-analysis/ etc.—the lang-rust- prefix duplicates the .../rust/ path segment. Strip it so pages live at clean paths like /docs/languages/rust/static-analysis/. Verified with a Hugo build: section index stays at /docs/languages/rust/, all leaf pages and page-bundle assets (dylint SVG, dynamic-analysis PNGs) publish and resolve correctly. Scope limited to the (unreleased) Rust chapter; C/C++ slugs left unchanged.
- security-overview: grammar ("A code" -> "Code"), "widthness" -> "width",
"signedness related" -> "signedness errors"; point overflow links at
stable primitive::i32 methods instead of unstable intrinsics
- dynamic-analysis: shuffle commands require nightly (cargo +nightly);
"Require" -> "Requires"; drop stray trailing hard-breaks
- gotchas: move comma out of todo! link; https for unimplemented! link
- memory-zeroization: fix comma splice + missing article; clarify the
secrecy comments (sequential move-then-print was a use-after-move);
subject/verb agreement
- model-checking: replace removed "cargo kani --visualize" with current
concrete-playback (print/inplace + playback); fix Creusot repo URL;
describe the unwinding-assertion failure precisely
- _index: "our rust-review skill" to match sibling chapter phrasing
… methods, not macros The dynamic-analysis chapter listed prop_map!, prop_filter!, and prop_recursive! as macros. Only prop_oneof! is a macro; the other three are methods on the Strategy trait. Verified against proptest 1.11.0: the macro forms fail with 'cannot find macro ... in this scope', while the method forms compile cleanly.
The documented cargo vet output was missing the blank line that the tool prints between "Vetting Failed!" and the "N unvetted dependencies:" summary. Verified against cargo-vet 0.10.2 by reproducing a failing vet run on a project depending on regex (regex-syntax unvetted).
The doc described must_use_candidate as "Checks for unused #[must_use] candidates," which is backwards. Per clippy source, the lint flags public functions that have NO #[must_use] attribute but return a non-must-use value and could be marked with one. Verified empirically with clippy on Rust 1.91.0: the lint fires on an unmarked pub fn with the message "this function could have a #[must_use] attribute."
Two defects, both verified empirically on Rust 1.91.0 / nightly 1.97.0: - The command uses -Zcrate-attr, a nightly-only -Z flag, but had no note that nightly is required. On stable it fails with "error: the option \`Z\` is only accepted on the nightly compiler." Switched to \`cargo +nightly clippy\` and \`rustc +nightly\`, and noted the requirement. - clippy::pedantic had no explicit -W; its -W was supplied only by the trailing separator of \`awk ORS=" -W"\`, so any reformatting would silently turn it into a bare positional arg. Replaced the awk stitching with \`sed s/^/-W /\` (explicit -W per lint) and wrote -W clippy::pedantic explicitly. Verified both forms emit identical warnings.
clippy-sarif is piped to at two places but its installation was never documented (unlike cargo-dylint, which has an explicit "Install the tool" step). Running the command verbatim fails with "command not found" (exit 127) because clippy-sarif is a separate crate, not shipped with clippy/cargo/rustup. Added an "Install the tool:" step with "cargo install clippy-sarif" at first use, matching the dylint section. Verified: after install, the pipe exits 0 and emits valid SARIF 2.1.0.
The overview stated overflow panics "in debug builds" and wraps "in
release builds," attributing the behavior to the build profile. It is
actually governed by the overflow-checks codegen setting; the profile
only sets its default. Verified empirically on Rust 1.91.0: an optimized
("release") build compiled with -C overflow-checks=on panics on 255u8+1
(exit 101), while an unoptimized build with overflow-checks=off wraps to
0. Kept the original "default behavior is to... except..." framing per
review and appended that the default is configurable via overflow-checks.
- Normalize {{< /tab >}} closing shortcode spacing (11 occurrences)
- Drop stray "?:" query suffix from coverage-report links
- Bump cast_checks 0.1.5 -> 0.1.6 (latest on crates.io)
- Fix subject-verb agreement: "engine and format ... are"
- Capitalize "HTML" (report text and tab label)
- Use "sh" code fence for the Semgrep command (was "bash")
- Replace escaped "\-" with em-dash in the string-conversion list
- "This Trail of Bits' tool" -> "This Trail of Bits tool"
- Dockerfile: use apt-get instead of apt
Corrections from pre-release review of the Rust chapter:
- 20-dynamic-analysis: fix broken cargo-llvm-cov anchor
(#exclude-function-from-coverage -> #exclude-code-from-coverage);
normalize `-Z sanitizer=` to `-Zsanitizer=` (matches -Zbuild-std elsewhere
and official docs); quote `info: running`; "most heavy" -> "heaviest";
silence unused-var warnings in example snippets (let _ / let _z).
- 50-memory-zeroization: correct ZeroizeOnDrop mechanics (derive generates a
Drop impl that zeroizes each field, skipping #[zeroize(skip)]; each field
must impl Zeroize/ZeroizeOnDrop) per zeroize_derive source; re-point the
moves-create-copies claim to benma's blog and describe it accurately
(memcpy, source not zeroed); add best-effort caveat that Drop is not
guaranteed to run (mem::forget, ManuallyDrop, Rc/Arc cycles, abort,
process::exit); `pin` feature -> `Pin` type; drop redundant "RAM memory".
- 30-static-analysis: correct string_slice lint description (flags all &str
slicing); make lint-name flags consistently underscore-cased.
- 10-security-overview: clearer overflow-method phrasing
("wrap and report the overflow", "check (returning an Option)").
- 60-model-checking: Aeneas backends are F*, Coq, HOL4, and Lean;
"constant time" -> "constant-time".
- materials/rust/coverage: rename placeholder crate tmp -> coverage-example
(builds, 6 tests pass); combine Dockerfile apt layers with
--no-install-recommends and clean apt lists.
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.
Introduces new chapter about various Rust testing methods.
The
.github/workflows/markdown.ymledits are needed to make lychee work.