How Rustlings Uses Clippy to Check Exercises: A Deep Dive into the Linting Pipeline

Rustlings integrates Clippy directly into the exercise execution pipeline, running cargo clippy --profile test with optional -D warnings after tests to enforce idiomatic Rust code.

The Rustlings project employs Clippy as a mandatory quality gate for every exercise. By embedding lint checks directly into the run command execution flow, the tool ensures learners write warning-free, idiomatic Rust code before proceeding. This article examines the implementation details in the rust-lang/rustlings repository to show exactly how the Clippy integration works.

The Exercise Execution Pipeline

When a user executes rustlings run <exercise_name>, the program follows a strict pipeline that includes mandatory Clippy linting. The process is orchestrated in src/exercise.rs through the RunnableExercise::run implementation.

Loading Metadata from info.toml

Each exercise's Clippy behavior is controlled by metadata defined in info.toml. The ExerciseInfo struct in src/info_file.rs (lines 15-20) deserializes the strict_clippy boolean flag:

// From src/info_file.rs
pub struct ExerciseInfo {
    pub name: String,
    pub dir: String,
    pub test: bool,
    pub strict_clippy: bool,  // Determines if warnings become errors
    pub hint: String,
}

This flag is stored in the Exercise struct (lines 71-76 of src/exercise.rs) and evaluated during execution to determine whether Clippy warnings should abort the run.

Constructing the Clippy Command

The core linting logic resides in src/exercise.rs (lines 44-52). After building the binary and running tests, the runner constructs a Clippy command using the internal cmd_runner:

let mut clippy_cmd = cmd_runner.cargo("clippy", bin_name, output.as_deref_mut());
// `--profile test` ensures #[cfg(test)] code is linted as well.
if FORCE_STRICT_CLIPPY || self.strict_clippy() {
    // `-D warnings` turns every Clippy warning into a compile-error.
    clippy_cmd.args(["--profile", "test", "--", "-D", "warnings"]);
} else {
    clippy_cmd.args(["--profile", "test"]);
}
let clippy_success = clippy_cmd.run("cargo clippy …")?;

The --profile test argument is always included to ensure that test code marked with #[cfg(test)] is also subject to linting.

Result Handling and Success Criteria

The final success of an exercise depends on both Clippy and binary execution. As shown in lines 53-57 of src/exercise.rs, the exercise only passes if clippy_success && run_bin evaluates to true:

let run_success = run_bin(&output)?;
let success = clippy_success && run_success;
Ok(success)

If strict_clippy is enabled and Clippy emits any warnings, the exercise is immediately marked as failed regardless of whether the binary runs correctly.

Configuration Files and Lint Rules

Rustlings enforces code quality through two layers of configuration: workspace-level lints that apply to the entire project and project-specific rules that customize Clippy's behavior.

Workspace-Level Lints in Cargo.toml

The repository defines strict Clippy policies globally in the [workspace.lints.clippy] section of Cargo.toml (lines 77-84). This configuration forbids specific patterns across all exercises:

[workspace.lints.clippy]
pedantic = "warn"
nursery = "warn"

# Additional specific lints may be configured here

These settings ensure consistent code style across the entire rustlings codebase and prevent common anti-patterns from being introduced into exercises.

Project-Specific Rules in clippy.toml

For granular control, the clippy.toml file at the repository root defines disallowed types and methods specific to the Rustlings learning context:

disallowed-types = [
  { path = "std::mem::uninitialized", reason = "Unsafe, use MaybeUninit instead" },
]
disallowed-methods = [
  { path = "std::thread::spawn", replacement = "std::thread::Builder::spawn", reason = "Handle errors properly" },
]

When exercise code uses any of the listed items, Clippy emits a warning (or error if -D warnings is active), guiding learners toward safer alternatives.

Continuous Integration Enforcement

The quality gates are enforced in CI via .github/workflows/rust.yml (lines 22-25). Every pull request and push triggers a strict Clippy check:

- name: Run Clippy
  run: cargo clippy -- --deny warnings

This ensures that the repository itself maintains a warning-free state and that all exercises meet the project's idiomatic Rust standards before merging.

Summary

  • Metadata-driven configuration: The strict_clippy flag in info.toml (parsed by src/info_file.rs) determines whether individual exercises treat Clippy warnings as fatal errors.
  • Pipeline integration: Every exercise execution runs cargo clippy --profile test after tests, with optional -D warnings for strict mode, as implemented in src/exercise.rs.
  • Dual-layer linting: Workspace-level rules in Cargo.toml and project-specific restrictions in clippy.toml combine to enforce comprehensive code quality.
  • CI enforcement: GitHub Actions runs cargo clippy -- --deny warnings on every commit to maintain repository-wide standards.

Frequently Asked Questions

Does every Rustlings exercise run Clippy?

Yes. Every exercise executes cargo clippy --profile test during the rustlings run command. However, only exercises with strict_clippy = true in their info.toml configuration will fail on warnings; others display warnings but allow the exercise to pass.

What is the difference between strict and non-strict Clippy mode?

Strict mode (strict_clippy = true) appends -D warnings to the Clippy command, turning every lint warning into a compile error that aborts the exercise. Non-strict mode runs Clippy without the deny flag, displaying warnings for educational purposes without blocking progression.

How can I see the exact Clippy command Rustlings runs?

The command construction happens in src/exercise.rs (lines 44-52). Rustlings internally builds a cargo clippy command with --profile test and optionally -- -D warnings. While the tool does not print the raw command to the terminal, you can inspect the source or run cargo clippy --profile test -- -D warnings manually in the exercise directory to replicate the strict behavior.

Can I customize Clippy rules for my own Rustlings fork?

Yes. Modify clippy.toml to add project-specific disallowed types or methods, or edit the [workspace.lints.clippy] section in Cargo.toml to adjust workspace-wide lint levels. You can also set the FORCE_STRICT_CLIPPY constant in the source code to enforce strict mode globally across all exercises regardless of individual info.toml settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →