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

> Discover how Rustlings uses Clippy to check exercises. Learn about the integrated linting pipeline that enforces idiomatic Rust code after running tests.

- Repository: [The Rust Programming Language/rustlings](https://github.com/rust-lang/rustlings)
- Tags: internals
- Published: 2026-03-05

---

**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`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/info.toml). The `ExerciseInfo` struct in [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/src/info_file.rs) (lines 15-20) deserializes the `strict_clippy` boolean flag:

```rust
// 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`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs) (lines 44-52). After building the binary and running tests, the runner constructs a Clippy command using the internal `cmd_runner`:

```rust
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`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs), the exercise only passes if `clippy_success && run_bin` evaluates to true:

```rust
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`](https://github.com/rust-lang/rustlings/blob/main/Cargo.toml) (lines 77-84). This configuration forbids specific patterns across all exercises:

```toml
[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`](https://github.com/rust-lang/rustlings/blob/main/clippy.toml) file at the repository root defines disallowed types and methods specific to the Rustlings learning context:

```toml
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`](https://github.com/rust-lang/rustlings/blob/main/.github/workflows/rust.yml) (lines 22-25). Every pull request and push triggers a strict Clippy check:

```yaml
- 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`](https://github.com/rust-lang/rustlings/blob/main/info.toml) (parsed by [`src/info_file.rs`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/src/exercise.rs).
- **Dual-layer linting**: Workspace-level rules in [`Cargo.toml`](https://github.com/rust-lang/rustlings/blob/main/Cargo.toml) and project-specific restrictions in [`clippy.toml`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/clippy.toml) to add project-specific disallowed types or methods, or edit the `[workspace.lints.clippy]` section in [`Cargo.toml`](https://github.com/rust-lang/rustlings/blob/main/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`](https://github.com/rust-lang/rustlings/blob/main/info.toml) settings.