async-rust-lsp
A standalone LSP server that provides real-time diagnostics for async Rust antipatterns — focusing on patterns that clippy and rust-analyzer miss.
Problem
Existing Rust tooling has a blind spot for tokio-specific async antipatterns:
- clippy only checks
std::sync::Mutexacross.await, nottokio::sync::Mutex - rust-analyzer has no plugin system for custom diagnostics
- Runtime tools (tokio-console) only help during execution, not during editing
This LSP fills the gap with real-time editor feedback for async lock patterns, blocking operations in async contexts, and other tokio-specific footguns.
Goals
Diagnostics
- tokio-mutex-across-await: Warn when
tokio::sync::Mutex/RwLockguards are held across.awaitpoints - blocking-in-async: Detect
std::thread::sleep,std::fs::*, and other blocking calls inside async functions - nested-lock-ordering: Flag potential deadlocks from inconsistent lock acquisition order
- unbounded-channel-in-loop: Warn about unbounded channel sends in hot loops
LSP Features
textDocument/publishDiagnostics— real-time warnings as you typetextDocument/codeAction— quick fixes (scope the guard, clone Arc, usespawn_blocking)- Incremental parsing via
tree-sitter-rustfor fast feedback
Integration
- Works with any LSP-compatible editor (VS Code, Zed, Neovim, Helix)
- Claude Code consumes LSP diagnostics automatically — diagnostics appear in agent context
- Configurable via
.async-rust-lsp.tomlper project
Architecture (aspirational)
┌─────────────┐ LSP/stdio ┌──────────────────┐
│ Editor │ ◄─────────────► │ async-rust-lsp │
│ (or Claude) │ │ │
└─────────────┘ │ tree-sitter-rust│
│ + custom rules │
└──────────────────┘
Built with:
tower-lsp— async LSP frameworktree-sitter-rust— incremental Rust parser- Custom rule engine for async pattern matching
Origin
Born from a real deadlock in the nteract desktop daemon. See nteract/desktop#1614. The gap in static analysis for tokio async patterns is well-known but no one has filled it with an LSP yet.
License
MIT