| Crates.io | cargo-fa |
| lib.rs | cargo-fa |
| version | 0.11.1 |
| created_at | 2025-12-21 20:14:32.13451+00 |
| updated_at | 2025-12-26 00:10:21.163049+00 |
| description | Static analysis tool for framealloc - detect memory intent violations before runtime |
| homepage | https://github.com/YelenaTor/framealloc/tree/main/cargo-fa |
| repository | https://github.com/YelenaTor/framealloc |
| max_upload_size | |
| id | 1998531 |
| size | 175,892 |
Static analysis for framealloc — catch memory intent violations before runtime
Installation • Usage • Diagnostics • CI Integration
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.
| 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 |
cargo install cargo-fa
Or from source:
git clone https://github.com/YelenaTor/framealloc
cd framealloc/cargo-fa
cargo install --path .
# 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
# 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
# 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
# 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
| 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) |
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()`
$ 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
...
- 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
stage('Static Analysis') {
sh 'cargo fa --all --format checkstyle > checkstyle.xml'
recordIssues tools: [checkStyle(pattern: 'checkstyle.xml')]
}
# 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
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"
Licensed under either of:
at your option.