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-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 Completionsifmatchの構文パターン補完
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では拡張機能マーケットプレイスから数クリックで導入できます。

  1. VS Codeの拡張機能パネルを開く(Ctrl+Shift+X)
  2. 検索欄に rust-analyzer と入力
  3. 「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パッケージと専用アダプタを利用します。

  1. Package Controlから「LSP」をインストール
  2. Package Controlから「LSP-rust-analyzer」をインストール
  3. 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を長時間占有する場合、次の対策が有効です。

  1. cargo.buildScripts.enablefalse に設定 – ビルドスクリプトの実行を無効化
  2. procMacro.enablefalse に設定 – 手続きマクロ展開を無効化
  3. 不要な依存クレートの削減Cargo.tomlで未使用のdependenciesを整理
  4. 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が動作しない場合のチェックリストです。

  1. 旧「Rust」(rls)拡張機能が残っていないか確認
  2. Output パネル → 「rust-analyzer」チャンネルでエラーログを確認
  3. rustup show でツールチェインが正しくインストールされているか確認
  4. VSCodeを再起動(コマンドパレットから「Developer: Reload Window」)

RLSとrust-analyzerの違い

2020年以前のRust開発では、RLS(Rust Language Server)が公式の言語サーバでした。RLSはコンパイラ(rustc)のAPIに依存しており、以下の課題がありました。

比較項目RLSrust-analyzer
アーキテクチャrustcのAPIをラップ独自のインクリメンタル解析エンジン
応答速度編集ごとに全体再解析が必要な場合あり変更差分のみ再解析
マクロ対応限定的手続きマクロを含め広範に対応
開発状態2022年にアーカイブ済み活発に開発中(毎週リリース)
Rust公式旧公式現行の公式LSP実装

RLSは2022年にアーカイブされ、現在は新規インストールが推奨されていません。既存のRLS設定を使用している場合は、rust-analyzerへの移行が必要です。

rust-analyzerの開発動向

rust-analyzerは毎週月曜日に新バージョンがリリースされており、2026年2月時点でChangelog #314まで公開されています。

最近の注目アップデートには以下のようなものがあります。

  • ビルトインderiveの専用処理: deriveマクロ展開を個別に最適化し、セルフコンパイル時に約180MBのメモリ削減を実現
  • 型ミスマッチ診断の安定化: 型エラーの検出精度が向上
  • マクロセグメント補完: マクロ定義内でのコード補完が改善
  • パラメータインレイヒント: 未指定の引数に対するインレイヒントの追加

出典: rust-analyzer Changelog

今後はプラグインAPIの整備が予定されており、サードパーティ開発者がrust-analyzerの機能を拡張できる仕組みが構築されつつあります。

まとめ

rust-analyzerは、Rust開発における標準的なLSP実装として定着しています。コード補完や型推論表示といった基本機能だけでなく、マクロ展開の可視化やメモリレイアウト表示など、Rust特有の解析機能を備えている点が特徴です。

VS Code・Neovim・Emacs・Sublime Textのいずれでも利用可能であり、設定の柔軟性も高いため、チームで異なるエディタを使っていても統一された開発体験を得られます。パフォーマンスの問題が発生した場合は、proc macroやfeatureフラグの制御、lspmuxの導入などで対処可能です。