LSP(Language Server Protocol)の役割とrust-analyzerの位置づけ
LSP(Language Server Protocol)は、Microsoftが策定したエディタと言語解析エンジン間の通信規約です。JSON-RPC 2.0をベースとし、コード補完・定義ジャンプ・リネームといったIDE機能をエディタ側と言語側で分離しています。この仕組みにより、1つの言語サーバを複数のエディタから共有できます。
出典: Language Server Protocol 公式仕様によれば、2025年時点で約300の言語サーバと50のエディタがLSPに対応しています。
rust-analyzerは、Rust言語向けのLSP実装です。Rustの旧式言語サーバであったRLS(Rust Language Server)の後継として開発が進み、2022年2月にRustプロジェクト公式の傘下に入りました。GitHubリポジトリは16,000以上のスターを獲得しており、Ferrous Systemsを中心に活発な開発が続いています。
rust-analyzerが備える機能の全体像
rust-analyzerは単なるコード補完ツールではなく、Rust開発に必要なIDE機能を幅広くカバーしています。以下に主要機能をカテゴリ別に整理します。
ナビゲーション系
| 機能 | 説明 | ショートカット例(VSCode) |
|---|---|---|
| Go to Definition | 関数・構造体の定義元へジャンプ | F12 |
| Go to Implementation | トレイト実装へジャンプ | Ctrl+F12 |
| Go to Type Definition | 変数の型定義へジャンプ | - |
| Find All References | 使用箇所を一覧表示 | Shift+Alt+F12 |
| Workspace Symbol | ワークスペース全体のシンボル検索 | Ctrl+T |
| Parent Module / Child Modules | モジュール階層の移動 | - |
コード補完・編集支援
| 機能 | 説明 |
|---|---|
| Auto Import | 未インポートの型・関数を補完時に自動追加 |
| Magic Completions | ifやmatchの構文パターン補完 |
| Rename | プロジェクト全体でのリネーム(F2) |
| Join Lines | 複数行を1行に結合 |
| Move Item | 関数・構造体を上下に移動 |
| On Typing Assists | 入力中の自動フォーマット |
インレイ表示・ハイライト
| 機能 | 説明 |
|---|---|
| Inlay Hints | 推論された型やパラメータ名をエディタ上に表示 |
| Hover | ホバー時にドキュメントと型シグネチャを表示 |
| Semantic Highlighting | 構文解析だけでなく意味解析に基づいた色分け |
| Highlight Related | カーソル位置と関連する箇所をハイライト |
解析・デバッグ支援
| 機能 | 説明 |
|---|---|
| Expand Macro Recursively | マクロ展開結果を確認 |
| View Syntax Tree | 構文木を可視化 |
| View Crate Graph | クレート依存関係をSVG表示 |
| View Memory Layout | 構造体のメモリレイアウトを確認 |
| View HIR / MIR | 中間表現を表示 |
各エディタへの導入手順
VS Codeの場合
VS Codeでは拡張機能マーケットプレイスから数クリックで導入できます。
- VS Codeの拡張機能パネルを開く(Ctrl+Shift+X)
- 検索欄に
rust-analyzerと入力 - 「rust-analyzer」(発行者: rust-lang)をインストール
旧拡張機能「Rust」(rls)がインストール済みの場合は、先にアンインストールしてからrust-analyzerを導入してください。競合するとコード補完やエラー表示が重複します。
インストール後、Rustプロジェクト(Cargo.tomlが存在するディレクトリ)を開くと自動的にrust-analyzerが起動します。
Neovimの場合
Neovimでは組み込みのLSPクライアント(vim.lsp)を使う方法が標準的です。
前提条件:
- Neovim 0.10以降を推奨
- rust-analyzerバイナリがPATH上にあること
rust-analyzerのバイナリは以下のいずれかで入手します。
# rustupから取得(推奨)
rustup component add rust-analyzer
# Cargoから直接ビルド
cargo install rust-analyzer
nvim-lspconfig プラグインを使った設定例です。
-- init.lua
local lspconfig = require('lspconfig')
lspconfig.rust_analyzer.setup({
settings = {
['rust-analyzer'] = {
check = {
command = 'clippy', -- cargo checkの代わりにclippyを使用
},
cargo = {
allFeatures = true, -- すべてのfeatureを有効化
},
procMacro = {
enable = true, -- 手続きマクロの展開を有効化
},
},
},
})
Emacsの場合
Emacsでは lsp-mode または eglot(Emacs 29以降で標準搭載)を利用します。
eglotを使った設定例:
;; init.el
(use-package eglot
:hook (rust-mode . eglot-ensure)
:config
(add-to-list 'eglot-server-programs
'(rust-mode . ("rust-analyzer"))))
lsp-modeを使った設定例:
(use-package lsp-mode
:hook (rust-mode . lsp-deferred)
:custom
(lsp-rust-analyzer-server-command '("rust-analyzer"))
(lsp-rust-analyzer-cargo-watch-command "clippy"))
Sublime Textの場合
Sublime TextではLSPパッケージと専用アダプタを利用します。
- Package Controlから「LSP」をインストール
- Package Controlから「LSP-rust-analyzer」をインストール
Cargo.tomlがあるディレクトリを開くと自動起動
実用的なrust-analyzer設定リファレンス
プロジェクトの規模や開発スタイルに合わせて、rust-analyzerの動作を細かく調整できます。設定はエディタの設定ファイル(VSCodeならsettings.json)またはプロジェクトルートの.vscode/settings.jsonに記述します。
診断チェックの変更
デフォルトでは cargo check が実行されますが、clippy に切り替えるとより厳密なリント結果を得られます。
{
"rust-analyzer.check.command": "clippy"
}
インレイヒントの調整
型推論の結果やパラメータ名が画面上に表示されて煩わしい場合、個別にオン・オフを切り替えられます。
{
"rust-analyzer.inlayHints.typeHints.enable": true,
"rust-analyzer.inlayHints.parameterHints.enable": false,
"rust-analyzer.inlayHints.chainingHints.enable": true
}
ワークスペース構成の指定
モノレポや複数のCargo.tomlがあるプロジェクトでは、rust-analyzerがワークスペースを自動検出できないことがあります。その場合は明示的にパスを指定します。
{
"rust-analyzer.linkedProjects": [
"./backend/Cargo.toml",
"./shared/Cargo.toml"
]
}
保存時の自動チェック制御
保存のたびにチェックが走ると負荷が高い場合、チェックのトリガーを変更できます。
{
"rust-analyzer.checkOnSave": true
}
大規模プロジェクトでチェックに時間がかかる場合は、falseに設定して手動実行に切り替えることも選択肢の一つです。
パフォーマンスを改善するテクニック
大規模なRustプロジェクトでは、rust-analyzerの初期解析やメモリ消費が問題になることがあります。以下の手法で改善を図れます。
手続きマクロの制御
手続きマクロ(proc macro)の展開は負荷の原因になることがあります。パフォーマンスを優先する場合、展開を無効にすることで解析速度が向上します。
{
"rust-analyzer.procMacro.enable": false
}
ただし、#[derive(Serialize)]のような一般的なderiveマクロまで無効になるため、補完精度とのトレードオフが生じます。
featureフラグの絞り込み
allFeatures: trueにしていると、条件付きコンパイル対象のすべてのコードを解析するため負荷が増します。開発中に不要なfeatureを除外することで軽量化できます。
{
"rust-analyzer.cargo.features": ["feature_a", "feature_b"]
}
lspmuxによるLSPサーバの常駐化
エディタの起動・終了を頻繁に行う開発スタイルの場合、毎回rust-analyzerがインデックスを再構築するため待ち時間が発生します。lspmuxを使うと、LSPサーバをバックグラウンドで常駐させ、エディタ起動時に即座に接続できます。
# インストール
cargo install lspmux
# systemdユーザーサービスとして起動設定
mkdir -p ~/.config/systemd/user
systemdサービスファイルの例:
[Unit]
Description=LSP Multiplexer
[Service]
ExecStart=%h/.cargo/bin/lspmux server
Restart=always
[Install]
WantedBy=default.target
# サービスの有効化と起動
systemctl --user enable lspmux
systemctl --user start lspmux
Neovimのlspconfig設定でlspmux経由の接続に変更します。
lspconfig.rust_analyzer.setup({
cmd = { 'lspmux', 'connect', 'rust-analyzer' },
})
この構成では、大規模プロジェクトでもエディタ起動直後からLSP機能がフル利用可能になります。
rust-analyzerが動作しないときの対処法
ワークスペースの検出に失敗する
rust-analyzer failed to discover workspace というエラーが表示される場合、以下を確認します。
- エディタでプロジェクトルート(
Cargo.tomlがある階層)を開いているか - サブディレクトリにプロジェクトがある場合は
linkedProjectsで明示指定
{
"rust-analyzer.linkedProjects": ["./subdir/Cargo.toml"]
}
rust-analyzerのバージョン不一致
使用しているRustツールチェインのバージョンと、rust-analyzerのバージョンが大きくずれると正常に動作しない場合があります。
# 現在のrust-analyzerバージョンを確認
rust-analyzer --version
# rustupのrust-analyzerを最新に更新
rustup update
rustup component add rust-analyzer
古いRustバージョンに固定しているプロジェクトでは、そのバージョンに対応するrust-analyzerを個別にダウンロードし、server.path設定でバイナリのパスを指定する方法があります。
{
"rust-analyzer.server.path": "/path/to/specific/rust-analyzer"
}
CPU使用率が高い・動作が重い
rust-analyzerがCPUを長時間占有する場合、次の対策が有効です。
cargo.buildScripts.enableをfalseに設定 – ビルドスクリプトの実行を無効化procMacro.enableをfalseに設定 – 手続きマクロ展開を無効化- 不要な依存クレートの削減 –
Cargo.tomlで未使用のdependenciesを整理 rust-analyzer.files.excludeDirsで解析対象外ディレクトリを指定 –targetディレクトリや生成ファイルが多いディレクトリを除外
{
"rust-analyzer.cargo.buildScripts.enable": false,
"rust-analyzer.procMacro.enable": false,
"rust-analyzer.files.excludeDirs": ["target", "generated"]
}
VSCodeでrust-analyzerが起動しない
VSCodeで拡張機能をインストールしてもLSPが動作しない場合のチェックリストです。
- 旧「Rust」(rls)拡張機能が残っていないか確認
- Output パネル → 「rust-analyzer」チャンネルでエラーログを確認
rustup showでツールチェインが正しくインストールされているか確認- VSCodeを再起動(コマンドパレットから「Developer: Reload Window」)
RLSとrust-analyzerの違い
2020年以前のRust開発では、RLS(Rust Language Server)が公式の言語サーバでした。RLSはコンパイラ(rustc)のAPIに依存しており、以下の課題がありました。
| 比較項目 | RLS | rust-analyzer |
|---|---|---|
| アーキテクチャ | rustcのAPIをラップ | 独自のインクリメンタル解析エンジン |
| 応答速度 | 編集ごとに全体再解析が必要な場合あり | 変更差分のみ再解析 |
| マクロ対応 | 限定的 | 手続きマクロを含め広範に対応 |
| 開発状態 | 2022年にアーカイブ済み | 活発に開発中(毎週リリース) |
| Rust公式 | 旧公式 | 現行の公式LSP実装 |
RLSは2022年にアーカイブされ、現在は新規インストールが推奨されていません。既存のRLS設定を使用している場合は、rust-analyzerへの移行が必要です。
rust-analyzerの開発動向
rust-analyzerは毎週月曜日に新バージョンがリリースされており、2026年2月時点でChangelog #314まで公開されています。
最近の注目アップデートには以下のようなものがあります。
- ビルトインderiveの専用処理: deriveマクロ展開を個別に最適化し、セルフコンパイル時に約180MBのメモリ削減を実現
- 型ミスマッチ診断の安定化: 型エラーの検出精度が向上
- マクロセグメント補完: マクロ定義内でのコード補完が改善
- パラメータインレイヒント: 未指定の引数に対するインレイヒントの追加
今後はプラグインAPIの整備が予定されており、サードパーティ開発者がrust-analyzerの機能を拡張できる仕組みが構築されつつあります。
まとめ
rust-analyzerは、Rust開発における標準的なLSP実装として定着しています。コード補完や型推論表示といった基本機能だけでなく、マクロ展開の可視化やメモリレイアウト表示など、Rust特有の解析機能を備えている点が特徴です。
VS Code・Neovim・Emacs・Sublime Textのいずれでも利用可能であり、設定の柔軟性も高いため、チームで異なるエディタを使っていても統一された開発体験を得られます。パフォーマンスの問題が発生した場合は、proc macroやfeatureフラグの制御、lspmuxの導入などで対処可能です。