Skip to Content
i documentation
Contributing

How to send changes

Make a first spec case, run a focused check, and prepare a change for submission.

This page takes you from the development shell to a checked first change. For a language change, work in the order spec text, test, implementation. The standard defines the intended behavior; tests make the requirement repeatable.

Set up and build

From the repository root, use the setup in development.md:

git submodule update --init crates/ilang-binaryen/binaryen
devenv shell

Inside the shell, build the CLI. This is the build command from CI’s Build the release i step:

cargo build --release --locked -p ilang-cli

The CLI is the resulting target/release/i. For the commands below, set:

I=target/release/i

A first change, step by step

  1. Choose the rule. Read the spec paragraph for the behavior you want to exercise. For a language change, amend the rule first. For a missing regression test, keep the rule and add a case that demonstrates it.
  2. Find the smallest neighboring case. tests/spec/10/a1_entry_exports.i is a complete, small case for §10.2’s program entry. Inspect it from the repository root:
ls tests/spec/10/a1_entry_exports.i
tests/spec/10/a1_entry_exports.i
cat tests/spec/10/a1_entry_exports.i
// spec: 10.2
// expect: pass
main = () { Nil }
  1. Add a distinct case in the same form. Create a new .i file under the section directory for your rule and give it a descriptive, unused basename. Put the spec: and expect: lines first, then the complete module. This existing case needs no imports or package manifest: its main takes no arguments and returns Nil. expect: pass requires successful compilation and execution without a stop, and any collected tests must pass. For a different rule, replace the body with the smallest assertion or rejected expression that tests it, and use that rule’s section number. Use a compile-error or warning expectation only with the actual diagnostic code required by the rule.
  2. Run the case by its basename. The spec runner discovers cases recursively; no test-list edit is needed. Here is the command for the existing case above. Substitute the new basename when running your added case:
cargo test -p ilang-cli --test spec --locked -- a1_entry_exports

The selected-case output from the run used to check this page is:

ok   10/a1_entry_exports.i

spec: 1 of 1 cases passed at --opt 0 and --opt 2

The runner itself checks both --opt 0 and --opt 2. It compares each result to the header and compares the two levels to each other. Its header contract and discovery code are in crates/ilang-cli/tests/spec.rs.

  1. Implement and widen the check. Make the implementation satisfy the case and run the related layer. A library change belongs with the module’s tests. For example, these commands select the tests in std/test/bool_test.i:
"$I" test --project std --opt 0 bool_test
"$I" test --project std --opt 2 bool_test

Both commands passed with the supplied compiler. Each run ended with:

34 passed, 0 failed

The name filter selects tests to run; it does not make package checking module-local.

In the shared redesign worktrees, testing.md requires Cargo work to go through the heavy queue. The exact filtered command used for this page was:

/home/agent/Programming/i/.rd/cache/heavy direnv exec /home/agent/Programming/i cargo test -p ilang-cli --test spec --locked -- a1_entry_exports

Format, lint, and account for corpus effects

CI’s Verify rust-lint step runs the rust-lint part of scripts/dev-verify. Its Rust formatting and lint checks are:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings

The i part checks source formatting with the built release compiler:

"$I" fmt --check lib std bench examples

For the complete Rust lint and snippet checks, use:

./scripts/dev-verify rust-lint

The accepted parts are rust, rust-lint, rust-test, snippets, i, js, and editors. No argument runs rust, i, js, and editors in order. The building and testing page gives each layer’s commands and the CI steps that run them.

A language change must include its spec text, a case under tests/spec, and an account of its effect on tests/review. Expected corpus output is an observation, not the rule. Change an expectation only with the spec paragraph that requires it; review the separate semantic requirement and promote fixed known failures. The testing guide describes deliberate regeneration.

Sending the change

Recent commit subjects use plain English sentences describing the change. The README and development guide document development and checks, but the repository does not yet document a submission process. Its GitHub remote is nmnmcc/i; the issue tracker is the place to raise a question about how to submit a change.

See also