# How to Run Checks on Community Exercises During Development in Rustlings

> Learn to run checks on community exercises during development with rustlings dev check. Ensure your Rustlings contributions meet standards and verify solutions.

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

---

**Use `rustlings dev check` to validate that community exercises conform to Rustlings standards, or `rustlings dev check --require-solutions` to additionally verify that solution files exist and compile.**

When you are creating or maintaining **community exercises** for the rust-lang/rustlings project, you need to ensure your exercises meet the same quality standards as the official set. The `rustlings dev check` command provides a comprehensive validation suite that runs checks on community exercises during development, verifying everything from metadata consistency to compilation behavior.

## Understanding the Dev Check Command

The `dev check` subcommand is implemented in **[`src/dev/check.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/check.rs)**. It executes multiple validation stages in parallel, with each exercise or solution running in its own thread for performance.

### Basic Syntax and Options

```bash

# Basic validation (no solution files required)

rustlings dev check

# Full validation including solution compilation and formatting

rustlings dev check --require-solutions

```

The basic mode validates exercise metadata, file structure, and ensures exercises fail when run (indicating they are unsolved). The `--require-solutions` flag adds compilation checks for solution files and runs `rustfmt --check` on them.

## Validation Stages in rustlings dev check

The command runs through several independent validation stages, each targeting a specific aspect of exercise quality.

### Cargo.toml Sanity Checks

The `check_cargo_toml` function (lines 29‑55 of **[`src/dev/check.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/check.rs)**) verifies that the generated [`Cargo.toml`](https://github.com/rust-lang/rustlings/blob/main/Cargo.toml) matches the list of exercises defined in [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml). This ensures that `cargo run --bin <exercise_name>` works correctly for every exercise.

### Info File Consistency Validation

The `check_info_file_exercises` function (lines 59‑138) parses [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) and validates each exercise's metadata:

- Name length and forbidden characters
- Non-empty hint field
- Unique exercise names
- Source file contains `fn main()` and at least one `// TODO` comment

### Directory Hygiene Verification

The `check_unexpected_files` function ensures the `exercises/` directory contains only files declared in [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) (plus optional [`README.md`](https://github.com/rust-lang/rustlings/blob/main/README.md) files). It also enforces that nested directories are limited to one level deep.

### Unsolved Exercise Guard

The `check_exercises_unsolved` function (lines 199‑244) runs each exercise in a separate thread and verifies it **fails** (i.e., is not already solved). This prevents accidentally shipping exercises that are complete from the start.

If an exercise is intentionally solved (such as an introductory demo), set `skip_check_unsolved = true` in its [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) entry.

### Solution Validation (Optional)

When using `--require-solutions`, the `check_solutions` function (lines 277‑352):

- Executes every `solutions/….rs` file to verify compilation
- Runs `rustfmt --check` on all solution files
- Reports missing solution files as errors

## Setting Up a Community Exercise Repository

Before running checks, you need a correctly scaffolded community repository.

### Scaffolding a New Project

Use the `dev new` command implemented in **[`src/dev/new.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/new.rs)**:

```bash
rustlings dev new my_exercises
cd my_exercises

```

This creates:
- `exercises/` and `solutions/` directories
- An [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) template with required metadata format
- A minimal [`Cargo.toml`](https://github.com/rust-lang/rustlings/blob/main/Cargo.toml) for the exercise binaries

### Required File Structure

A valid community exercise repository must contain:

```

my_exercises/
├── Cargo.toml          # Auto-generated, kept in sync by dev check

├── info.toml           # Metadata for all exercises

├── exercises/
│   ├── exercise_name.rs
│   └── ...
└── solutions/
    ├── exercise_name.rs
    └── ...

```

## Typical Development Workflow

Follow this sequence when building community exercises:

1. **Create the repository scaffold** using `rustlings dev new my_exercises`

2. **Add an exercise** by editing [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) and creating [`exercises/your_name.rs`](https://github.com/rust-lang/rustlings/blob/main/exercises/your_name.rs) (must contain `fn main()` and a `// TODO` comment)

3. **Run basic checks** to validate metadata, file layout, and unsolved status:
   ```bash
   rustlings dev check
   ```

4. **Add a solution** by creating [`solutions/your_name.rs`](https://github.com/rust-lang/rustlings/blob/main/solutions/your_name.rs)

5. **Run full checks** including solution compilation and formatting:
   ```bash
   rustlings dev check --require-solutions
   ```

If any validation fails, the command outputs a specific error message with the file path, allowing immediate correction.

## Code Examples for Running Checks

### Basic Check Without Solutions

```bash

# From the root of your community exercises repository

rustlings dev check

```

Example output when validation passes:

```

Running all exercises to check that they aren't already solved...
Running all solutions...
Everything looks fine!

```

### Full Check With Solution Validation

```bash
rustlings dev check --require-solutions

```

If a solution file is missing, you will see:

```

The solution of the exercise my_exercise is missing

```

### Required TODO Comments

Every exercise source file must contain a `// TODO` comment for the info-file consistency check:

```rust
// exercises/my_exercise.rs
fn main() {
    // TODO: Fill in the blank
    println!("Hello, world!");
}

```

The `check_info_file_exercises` function specifically looks for this pattern to ensure exercises are incomplete by design.

### Handling Intentionally Solved Exercises

For introductory exercises that should pass immediately, disable the unsolved guard in [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml):

```toml
[[exercises]]
name = "intro"
skip_check_unsolved = true
hint = """This exercise is already solved."""

```

This configuration prevents the `check_exercises_unsolved` stage from failing on this specific exercise.

## Summary

- Use **`rustlings dev check`** to validate community exercise metadata, file structure, and unsolved status during development.
- Add **`--require-solutions`** to additionally verify that solution files exist, compile, and pass `rustfmt` checks.
- The validation logic resides in **[`src/dev/check.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/check.rs)**, with specific functions handling Cargo.toml sanity, info-file consistency, directory hygiene, and exercise compilation.
- Each exercise must contain a `// TODO` comment and `fn main()`, while the [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) file must define unique names and valid metadata.
- The check command is thread-safe and runs validations in parallel for optimal performance.

## Frequently Asked Questions

### What is the difference between `rustlings dev check` and `rustlings dev check --require-solutions`?

The basic `rustlings dev check` command validates that your [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) is correctly formatted, that all declared exercises exist in the `exercises/` directory, that each exercise contains a `fn main()` and `// TODO` comment, and that exercises fail when run (ensuring they are unsolved). When you add the `--require-solutions` flag, the command additionally checks that every exercise has a corresponding file in the `solutions/` directory, that these solution files compile successfully, and that they pass `rustfmt --check`.

### How do I create a new community exercise repository that works with `dev check`?

Use the scaffolding command `rustlings dev new PROJECT_NAME`, which is implemented in **[`src/dev/new.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/new.rs)**. This command generates a directory structure with `exercises/` and `solutions/` folders, a template [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) file with the correct format version, and a minimal [`Cargo.toml`](https://github.com/rust-lang/rustlings/blob/main/Cargo.toml). Once scaffolded, you can add your exercise files and run `rustlings dev check` to validate the structure before publishing.

### Why does my exercise fail the "unsolved" check, and how do I fix it?

The `check_exercises_unsolved` function in **[`src/dev/check.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/check.rs)** runs each exercise and expects it to fail (indicating it is incomplete). If your exercise passes compilation and execution, the check will fail unless you explicitly mark it as intentionally solved. To fix this, add `skip_check_unsolved = true` to the exercise's entry in [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml). This is appropriate for introductory exercises that demonstrate working code.

### What are the specific requirements for exercise source files?

According to the `check_info_file_exercises` validation in **[`src/dev/check.rs`](https://github.com/rust-lang/rustlings/blob/main/src/dev/check.rs)**, every exercise source file must contain two specific elements: a `fn main()` function (so the file can be executed as a binary), and at least one `// TODO` comment (indicating where the learner needs to make changes). Additionally, exercise names in [`info.toml`](https://github.com/rust-lang/rustlings/blob/main/info.toml) must be unique, contain no forbidden characters, and have a non-empty hint field.