Contributing
Vx is early. The most valuable contribution right now is a clear bug report: a program that should compile and does not, or one that compiles and does the wrong thing.
Reporting a bug
Open an issue at github.com/vx-lang/Vx/issues with:
- the smallest
.vxfile that reproduces it, - the exact command you ran,
- what you expected and what happened,
vxc --versionand your platform.
If the compiler produced MLIR, --emit-mlir output is often the fastest way to show what went
wrong.
Your first change
Issues labelled good first issue are self-contained and do not assume you know the compiler. Each one states the problem, shows the current behaviour, and says what the fix should look like.
A sample of what is open:
| Issue | What it is |
|---|---|
| Vx#506 | while is not a keyword, and a fixture appears to test it but does not |
| Vx#501 | invariant demands parentheses; requires and ensures do not |
| Vx#494 | The unused-variable warning fires on a variable used only through method calls |
| Vx#445 | Twelve warning codes are declared but never emitted |
| Vx#423 | Issue numbers in code comments, against a rule that forbids them |
If one of these is unclear, say so on the issue. A first issue that cannot be picked up cold is a bug in the issue, not in you.
help wanted holds larger pieces that are still well specified.
Working on the compiler
Start with building from source. Once cargo test passes you have a working
development setup.
For how the compiler is put together — the phase pipeline, the two code generators, how to add a language feature, and how the test tiers work — read the developer guide.
The repository layout:
src/ the vxc compiler (Rust)
lexer, parser/ source to AST
syntax/ AST, types, topologies, declarations
hir/ lowering, type checking, borrow checking
check/ transfer, calls, access, autodiff, region traffic
memory.rs the memory algebra: containment, capacity, derived cost
seam.rs asynchronous-visibility contracts
flatten.rs the flat, AST-annihilated path
codegen/ MLIR emission
dialect/ the Vx dialect and its lowering (C++)
plugin/ vendor MLIR pass plugins
fleet/ machine files
runtime/ dispatch and the distributed fleet runtime (C++)
stdlib/ the standard library
vx-analyzer/ language server
tests/ integration suites and unit tests
Conventions worth knowing
No locks in the compiler. A compilation has to be isolated, and CI rejects Mutex, RwLock,
OnceLock and friends anywhere under src/. Process-global atomics are banned for the same reason:
a static that a worker thread can write is shared mutable state whether or not it takes a lock to do
it, and a cached answer survives across compilations in a long-lived process such as the language
server.
Determinism is gated, not hoped for. Several tests assert that the pipeline emits byte-identical MLIR at one thread, at four, and with the thread pool off the path entirely. If your change makes output depend on iteration order, those will catch it.
Format before you commit. cargo fmt for Rust, vx-format for .vx files, clang-format for
C++. CI checks all three, and clippy runs with -D warnings.
Tests come with the change. New backend behaviour needs a fixture under tests/; the check
lines are generated by utils/update_mlir_test_checks.rs rather than written by hand.
Extending the compiler for new hardware
Vendors are not expected to patch the compiler. A new accelerator arrives as:
- a machine file declaring its memory hierarchy and interconnect, and
- an MLIR pass plugin under
src/plugin/that lowers the Vx dialect for that target.
docs/adding_a_topology.md walks through the process.