We welcome contributions! Please feel free to look through Issues and submit Pull Requests.
- When creating a PR, please ensure a corresponding issue has first been opened. The issue should detail the motivation for the changes, expected behaviours and, if the issue relates to bugs, it should include a minimal reproducible example.
- When adding new features, please include corresponding tests to ensure these are well-tested and behave as expected.
- Please ensure all PRs pass
just verifybefore submission.
This project uses Nix to manage the development environment.
- Install Nix Package Manager.
- Install nix-direnv (recommended) for automatic environment loading.
To set up the environment:
# If using direnv
direnv allow
# Or manually enter the shell
nix developThis will provide a shell with the correct Rust version and dependencies.
nix-direnv caches the dev shell for performance. If devenv/flake.nix or
devenv/flake.lock changes (e.g., after pulling new commits that update
dependencies or add tools), the cache may be stale and new tools will be
missing from your PATH.
Signs the cache is stale:
- A tool listed in
devenv/flake.nixis not found (e.g.,lychee: command not found). direnv exportoutput says "Using cached dev shell" after you know the flake changed.- A
justrecipe fails with a missing command even though the tool is in the flake.
To rebuild:
# Remove the cached shell and reload
rm -f .direnv/flake-profile* .direnv/nix-direnv.*
direnv allowIf using nix develop directly instead of direnv, exit and re-enter the shell.
All commands are run via just recipes defined in the project's justfile. Never run cargo directly; the justfile handles Nix environment setup automatically.
just fmt # Format all files (Rust, Nix, Markdown, YAML, TOML)
just clippy # Run clippy
just test # Run all tests (cached; only re-runs when content changes)
just doc # Build docs (must produce zero warnings)
just deny # Check licenses and advisories with cargo-deny
just verify # Run fmt, check, clippy, deny, doc, test in order
just clean # Remove build artifacts and test cacheRun just --list to see all available recipes.
When a command is expected to produce a large amount of output, use
just filtered instead of writing an ad-hoc shell pipeline. The first
argument is the just recipe to run, the second argument is a ripgrep
regex used to select output lines, and the remaining arguments are
forwarded to the selected recipe.
just filtered check '^(error|warning|[[:space:]]*-->)' -p fp-library --lib
just filtered test '^(test .* \.\.\. FAILED|failures:|error)' -p fp-library -- prop_just filtered preserves the selected recipe's exit status, rejects
unsupported recipes and unsafe forwarded arguments, and limits filtered
matches so accidental broad filters do not dump full logs.
The HM type signature generation system uses insta snapshot tests to guard against regressions. If you change the signature rendering code in fp-macros, snapshots may need updating.
# Run snapshot tests to see if any changed
just test -p fp-macros --lib -- snapshot
# Review and accept/reject changed snapshots interactively
just cargo insta review
# Accept all changed snapshots without review
just cargo insta acceptYou can also review snapshots manually by running the tests with INSTA_UPDATE=new and inspecting the .snap.new files in fp-macros/src/documentation/snapshots/.
When regenerating snapshots, make sure the tests actually rerun. The just test
cache key is based on tracked file contents and test arguments, not environment
variables such as INSTA_UPDATE. If you are rerunning the same test command to
regenerate snapshot files, run just clean first to clear the cached test output.
The just test banner lines (for example, === Running tests ===) are terminal
output only; they are not written into snapshot files.
Both fp-macros and fp-library use trybuild
for compile-fail tests. These are .rs files in tests/ui/ that must fail to compile,
with expected compiler output stored in matching .stderr golden files.
If your changes alter error messages (e.g., changing a proc macro's error output,
renaming types, or moving modules), the .stderr files need updating.
Signs a trybuild test is stale:
- Test output shows a diff between expected and actual compiler stderr.
- The diff contains changed file paths, line numbers, or error wording.
To update:
# Clear cached test output so TRYBUILD=overwrite reruns the tests
just clean
# Overwrite all stale .stderr files with current compiler output
TRYBUILD=overwrite just test
# Or update only a specific crate's tests
TRYBUILD=overwrite just test -p fp-macros
TRYBUILD=overwrite just test -p fp-libraryAlways review the updated .stderr files before committing to ensure the new
error messages are correct and intentional.
The just test banner lines (for example, === Running tests ===) are terminal
output only; they are not part of the compiler stderr captured by trybuild.
See the Project Structure documentation.
For maintainers, the release process is documented in release-process.md.
This project uses Criterion.rs for benchmarking to ensure zero-cost abstractions and detect performance regressions.
just bench -p fp-library # To run all benchmarks
just bench -p fp-library --bench benchmarks -- --list # To list available benchmarks
just bench -p fp-library --bench benchmarks -- Vec # To run a specific benchmark (e.g., `Vec`)Benchmark reports are generated in target/criterion/report/index.html.