GitHub Copilot CLI is a terminal coding agent that you start inside a Rust project folder by running copilot. It reads project instructions from .github/copilot-instructions.md or AGENTS.md, so you can teach it to use cargo, clippy, rustfmt, and your workspace layout. See GitHub Copilot CLI for the command basics; the rest of this guide is a Rust-specific workflow.
Rust strengths of a terminal-first agent
Rust development rewards a tight feedback loop between compiler errors and edits. GitHub Copilot CLI runs in the same terminal as cargo, so it can execute cargo check, read the exact borrow checker or trait bound error, and apply a fix without leaving the context. That is more useful than an IDE chat assistant for many Rust refactors because the agent sees real compiler output, not a guessed error message. It also follows workspace conventions from your instructions file, which matters when a crate has strict module boundaries, feature flags, or an internal error type hierarchy. For example, instructing it to run cargo clippy --all-targets --all-features -- -D warnings before every change prevents the agent from leaving behind warnings that later fail CI. Because Rust code often spans multiple files for a single trait or error change, the agent can update impl blocks, callers, and tests in one pass if you tell it which crates are allowed to change. Keep in mind that it is still an automated editor: you review every diff, especially changes to Cargo.toml, unsafe, and public API surface.
Configuring instructions for cargo workspaces
Before starting copilot, create either .github/copilot-instructions.md at the repository root or AGENTS.md in the same location. The agent reads these files as standing instructions, so keep them short, operational, and Rust-specific. Do not paste a generic style guide; use exact commands and folder rules the agent can check.
A realistic instructions file for a small Rust workspace looks like this:
# Rust project instructions
Run these commands before marking any change complete:
- `cargo fmt --check` — fix formatting with `cargo fmt` if needed
- `cargo clippy --all-targets --all-features -- -D warnings`
- `cargo test --all-features`
- `cargo build --all-features`
Workspace layout:
- `crates/core` — domain types and traits, no I/O, no async
- `crates/server` — HTTP and database code, depends on `core`
- `crates/cli` — binary, depends on `server` and `core`
Rules:
- Prefer `anyhow::Result` in application crates and `thiserror` in library crates.
- Do not add new `unsafe` blocks without a safety comment explaining why safe code cannot do the job.
- Keep async code in `server` only; `core` stays synchronous.
- When changing a public type, update all `impl` blocks, trait implementations, and tests in the same change.
- Use `src/foo.rs` plus `src/foo/` for submodules; do not create `mod.rs` files.
If you need a general startup sequence, How to use GitHub Copilot CLI covers the first run and basic interaction. The key for Rust is to encode commands that fail CI, not just style preferences.
A review-driven workflow with cargo checks
Start copilot in the project folder, then give it one focused task at a time. Ask it to state which files it will change and why before editing. After it reports done, run the verification commands yourself and inspect git diff before accepting anything.
A reliable loop looks like this:
- Describe the task and add constraints:
Do not reformat unrelated code and do not change the public API. - Let the agent propose a plan, then approve or adjust it.
- After edits, run
cargo test --all-features,cargo clippy --all-targets --all-features -- -D warnings, andcargo fmt --check. - Review
git diff --statfirst, thengit difffor logic, lifetimes, and error handling changes. - If a command fails, paste the compiler or clippy output back into the same session and ask for a fix.
Example prompts for typical Rust tasks:
Add a From<sqlx::Error> implementation for ApiError that preserves the underlying error source without exposing sqlx in the public API.Refactor handle_request to return Result<Response, ApiError> instead of Box<dyn Error>; update all callers and add unit tests for the new error path.Add a --config flag to the CLI binary that loads a TOML file using clap and serde; include tests for a missing file and a malformed file.Fix the lifetime error in cache.rs by eliding lifetimes where possible, but first explain the ownership change you are making.Move serde and tokio to workspace dependencies, then run cargo update -p for the affected packages and verify tests still pass.
When you give such prompts, the agent can usually handle the mechanical parts of the change; the review step is where you catch lifetime shortcuts and API breaks.
Tasks that work well and Rust pitfalls to monitor
The agent is strong at repetitive, cross-file changes: adding trait implementations, converting error types, updating module paths, writing tests from a function signature, and moving types between crates. It is also decent at resolving simple lifetime errors by elision or by adding an explicit lifetime where the intent is obvious. It can update Cargo.toml for dependency version bumps and workspace inheritance if the instructions are clear.
Watch closely in these Rust-specific areas:
- Lifetimes: the agent may introduce
'staticorBox::leakto silence the borrow checker, which hides a real ownership problem. - Unsafe: it might suggest an
unsafeblock to bypass a check; require a safety comment and a good reason. - Async and Send/Sync: moving a type across an
awaitor into a spawned task can change itsSendandSyncbounds; verify that the change still compiles with the intended executor. - Public API: a small change to a struct or enum can break semver compatibility; the agent may not know which types are public unless you tell it.
- Feature unification: in a workspace, adding a dependency or enabling a feature in one crate can affect the whole build; use
cargo check --workspace --all-featuresbefore finalizing. - Clippy lints: the agent may add
#[allow(...)]to silence a lint instead of fixing the underlying issue; reject blanket allows. - Integer and float types: it may choose
usizeoru64inconsistently, causing type mismatch errors later.
Ask the agent to explain any non-obvious lifetime, unsafe, or async change before accepting it. That explanation often reveals whether it understood the problem.
Verifying changes with cargo, clippy, and tests
Verification is the part you should never outsource completely. Have the agent run the commands, but read the output yourself before trusting the change. The table below shows the standard Rust verification commands and what they catch.
| Command | What it verifies |
|---|---|
cargo check --all-targets | Fast type checking without codegen; catches borrow checker, trait bound, and type mismatch errors. |
cargo test --all-features | Runs unit and integration tests across all feature combinations in the workspace. |
cargo clippy --all-targets --all-features -- -D warnings | Lints for correctness, idiomatic Rust, performance, and style; fails on any warning. |
cargo fmt --check | Formatting consistency; use cargo fmt to apply changes. |
For larger workspaces, a codebase map for AI agents can help the agent find the right module before editing, reducing the chance of touching unrelated crates. After each agent turn, run at least cargo check and the relevant tests. If you changed functionality in an unsafe block or a low-level crate, consider running the tests under Miri if you already use it; otherwise, keep the change review tight.
Parallel agents with git worktrees in AgentVera
For parallel Rust work, AgentVera runs GitHub Copilot CLI and other coding agents each in its own real terminal panel and git worktree, so parallel agents edit separate working trees instead of overwriting shared files. Automatic code review after each turn sends findings with file:line links, which helps when an agent introduces a lifetime or unsafe change. Checkpoints snapshot every turn, so you can undo a broken borrow-checker experiment or replay the session step by step. This is especially useful in cargo workspaces where one agent refactors a crate while another works on a binary.
Wrap-up: build the habit of small verifiable changes
GitHub Copilot CLI becomes a reliable Rust pair programmer when you give it explicit cargo commands, workspace rules, and small, reviewable tasks. Keep the loop tight: plan, edit, run cargo test and clippy, review the diff. Use AgentVera when you need multiple agents on separate worktrees with code review and checkpoints.