9 releases (breaking)
| new 0.11.1 | Dec 26, 2025 |
|---|---|
| 0.11.0 | Dec 23, 2025 |
| 0.10.0 | Dec 23, 2025 |
| 0.9.0 | Dec 23, 2025 |
| 0.5.1 | Dec 21, 2025 |
#172 in Memory management
160KB
3.5K
SLoC
cargo-fa
Static analysis for framealloc — catch memory intent violations before runtime
Installation • Usage • Diagnostics • CI Integration
Overview
cargo-fa is a static analysis tool for framealloc that detects memory intent violations at build time. It catches patterns that compile but violate frame allocation principles — issues that would otherwise only surface as performance problems or subtle bugs at runtime.
What It Catches
| Category | Examples |
|---|---|
| Lifetime Issues | Frame allocations escaping scope, hot loop allocations |
| Async Safety | Frame data crossing await points, closure captures |
| Threading | Cross-thread frame access, missing thread-local init |
| Architecture | Tag mismatches, unknown tags, module boundary violations |
| Budgets | Unbounded allocation loops |
Installation
cargo install cargo-fa
Or from source:
git clone https://github.com/YelenaTor/framealloc
cd framealloc/cargo-fa
cargo install --path .
Usage
Basic Checks
# Check specific categories
cargo fa --dirtymem # Lifetime/escape issues (FA6xx)
cargo fa --async-safety # Async/await issues (FA7xx)
cargo fa --threading # Thread safety issues (FA2xx)
cargo fa --budgets # Budget violations (FA3xx)
cargo fa --architecture # Tag/module issues (FA8xx)
# Run all checks (optimized order)
cargo fa --all
Filtering
# Treat specific diagnostic as error
cargo fa --all --deny FA701
# Suppress specific diagnostic
cargo fa --all --allow FA602
# Exclude paths (glob pattern)
cargo fa --all --exclude "**/tests/**"
# Stop on first error
cargo fa --all --fail-fast
# Minimum severity threshold
cargo fa --all --min-severity warning
Output Formats
# Human-readable (default)
cargo fa --all
# JSON for programmatic consumption
cargo fa --all --format json
# SARIF for GitHub Actions
cargo fa --all --format sarif
# JUnit XML for test reporters
cargo fa --all --format junit
# Checkstyle XML for Jenkins
cargo fa --all --format checkstyle
# Compact one-line-per-issue
cargo fa --all --format compact
Subcommands
# Explain a diagnostic code in detail
cargo fa explain FA601
# Analyze a single file
cargo fa show src/physics.rs
# List all diagnostic codes
cargo fa list
# Filter by category
cargo fa list --category async
# Generate configuration file
cargo fa init
Diagnostics
Diagnostic Codes
| Range | Category | Description |
|---|---|---|
| FA2xx | Threading | Cross-thread frame access, thread-local issues |
| FA3xx | Budgets | Unbounded allocations, missing budget guards |
| FA6xx | Lifetime | Frame escape, hot loops, missing boundaries |
| FA7xx | Async | Await crossing, closure capture, async functions |
| FA8xx | Architecture | Tag mismatch, unknown tags, module violations |
| FA9xx | Rapier | Physics engine integration issues (Rapier 0.31) |
Example Output
error[FA701]: frame allocation in async function
--> src/network/client.rs:45:12
|
45 | let buffer = alloc.frame_box(vec![0u8; 1024]);
| ^^^^^^ frame allocation here
|
= note: async functions can suspend across frame boundaries
= help: use `alloc.heap_box()` or `alloc.pool_box()` instead
warning[FA602]: allocation in hot loop
--> src/physics/collision.rs:128:16
|
128| let contact = alloc.pool_alloc::<Contact>();
| ^^^^^^ allocation inside loop
|
= note: loop may execute many times per frame
= help: consider pre-allocating with `alloc.frame_vec()`
Getting Detailed Explanations
$ cargo fa explain FA701
━━━ FA701 ━━━
Name: async-frame
Category: Async Safety
Severity: error
Summary
Frame allocation in async function
Description
Async functions can suspend at await points. When they resume, they might
be on a different thread or at a different point in the frame lifecycle...
Example (incorrect)
async fn load_asset(alloc: &SmartAlloc) {
let buffer = alloc.frame_box(vec![0u8; 1024]); // FA701
...
Example (correct)
async fn load_asset(alloc: &SmartAlloc) {
let buffer = alloc.heap_box(vec![0u8; 1024]); // Safe
...
CI Integration
GitHub Actions (SARIF)
- name: Run cargo-fa
run: cargo fa --all --format sarif > results.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif
Jenkins (Checkstyle)
stage('Static Analysis') {
sh 'cargo fa --all --format checkstyle > checkstyle.xml'
recordIssues tools: [checkStyle(pattern: 'checkstyle.xml')]
}
Generic CI
# Exit with error on any issues
cargo fa --all --deny-warnings
# Exit with error only on specific codes
cargo fa --all --deny FA701 --deny FA702
Configuration
Create a .fa.toml in your project root:
cargo fa init
Example configuration:
[global]
enabled = true
exclude = ["target/**", "tests/**"]
[lints.FA601]
level = "warn"
[lints.FA701]
level = "deny"
[tags]
known = ["physics", "rendering", "audio", "network"]
[tags.modules]
"src/physics/**" = "physics"
"src/render/**" = "rendering"
Related
- framealloc — The memory allocation library
- TECHNICAL.md — Architecture documentation
License
Licensed under either of:
at your option.
Dependencies
~2–13MB
~112K SLoC