Rust Tooling and Code Quality

Rust Analyzer

rust-analyzer is the official Language Server Protocol (LSP) implementation for the Rust programming language. Unlike batch compilers that process an entire crate from start to finish, rust-analyzer maintains an incremental, query-driven semantic database in memory (powered by the Salsa incremental computation framework) to provide instantaneous IDE features in VS Code, Neovim, Helix, Zed, Emacs, and JetBrains IDEs.

Editor (VS Code / Neovim / Zed / Helix)
        |
        |  JSON-RPC over Language Server Protocol (LSP)
        v
[ rust-analyzer Incremental Query Engine ]
  ├── Real-time Type Inference & Inlay Hints (`let x: Vec<i32> = ...`)
  ├── Go to Definition / Find References / Rename Symbol
  ├── Context-Aware Code Assists (Fill Match Arms, Extract Function)
  ├── Macro & Procedural Macro Expansion Inspector
  └── Background `cargo check` / `cargo clippy` Flycheck Runner

High-Productivity rust-analyzer Capabilities

Capability How It Accelerates Rust Development
Inlay Hints Displays inferred variable types, closure parameter types, method chain intermediate types, and lifetime elision annotations inline without cluttering source files.
Code Actions / Assists Automatically generates missing match arms for an enum, converts an if let to a match, extracts expressions into functions, or generates a From / Default impl skeleton.
Macro Expansion (Expand Macro Recursively) Shows the exact token stream produced by declarative macro_rules! and procedural #[derive(...)] macros to debug complex macro errors.
Postfix Completions Typing expr.dbg, expr.ok, expr.some, expr.match, or expr.let expands into dbg!(expr), Ok(expr), Some(expr), match expr { ... }, or let var = expr;.
Runnable Lenses (Run / Debug / Test) Adds one-click code lenses directly above fn main(), #[test] functions, and doc-test blocks inside /// comments.

Recommended rust-analyzer Workspace Settings

Configuring rust-analyzer to run cargo clippy instead of cargo check on save surfaces Clippy lints directly in your editor as you type:

{
  "rust-analyzer.check.command": "clippy",
  "rust-analyzer.check.extraArgs": ["--all-targets"],
  "rust-analyzer.cargo.features": "all",
  "rust-analyzer.inlayHints.bindingModeHints.enable": true,
  "rust-analyzer.inlayHints.closureReturnTypeHints.enable": "with_block",
  "rust-analyzer.inlayHints.lifetimeElisionHints.enable": "skip_trivial",
  "rust-analyzer.procMacro.enable": true
}

Running Batch Analysis from the Command Line

rust-analyzer also includes CLI subcommands for diagnosing language server performance and batch-checking type inference across a workspace:

# Run rust-analyzer's internal type-checker and report memory/timing metrics
rust-analyzer analysis-stats .

# Parse and dump the syntax tree of a snippet from stdin
rust-analyzer parse < src/main.rs
#[derive(Debug, Clone, Copy)]
pub enum ConnectionState {
    Disconnected,
    Connecting { attempt: u8 },
    Connected { latency_ms: u32 },
}

pub fn describe_state(state: ConnectionState) -> String {
    // Using rust-analyzer's "Fill match arms" code action on `match state {}`
    // automatically populates all three variants below:
    match state {
        ConnectionState::Disconnected => "offline".to_string(),
        ConnectionState::Connecting { attempt } => format!("retrying (attempt #{attempt})"),
        ConnectionState::Connected { latency_ms } => format!("online ({latency_ms}ms)"),
    }
}

fn main() {
    let state = ConnectionState::Connected { latency_ms: 14 };
    println!("State: {}", describe_state(state));
}
State: online (14ms)