Skip to content

Rust chapter (updated version)#128

Merged
elopez merged 54 commits into
mainfrom
rust-chapter-v2
Jul 6, 2026
Merged

Rust chapter (updated version)#128
elopez merged 54 commits into
mainfrom
rust-chapter-v2

Conversation

@GrosQuildu

@GrosQuildu GrosQuildu commented May 7, 2026

Copy link
Copy Markdown
Collaborator

Introduces new chapter about various Rust testing methods.

The .github/workflows/markdown.yml edits are needed to make lychee work.

@GrosQuildu GrosQuildu changed the title init rust chapter Rust chapter (updated version) May 7, 2026
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-06 03:34 UTC

@GrosQuildu GrosQuildu mentioned this pull request May 13, 2026
@GrosQuildu
GrosQuildu marked this pull request as ready for review May 13, 2026 12:53
elopez added 28 commits July 4, 2026 14:51
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.
@elopez
elopez merged commit 3fe2091 into main Jul 6, 2026
5 of 6 checks passed
@elopez
elopez deleted the rust-chapter-v2 branch July 6, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants