⚙️

ひとくちメモ: VSCode で rust-analyzer 拡張をまともに動かす

に公開1

後述ながら、これは Remote-SSH 環境が前提なので注意。

結論

あんたの $HOME/home/mystere であると仮定して、以下を settings.json に追記する。また、この設定は環境間で非可搬である。よって、settingsSync.ignoredSettings にも以下の内容に対応するエントリーを追加することで、設定の同期を部分的に切ることをおすすめする。

{
  "rust-analyzer.cargo.extraEnv": {
    "CARGO": "/home/mystere/.cargo/bin/cargo",
    "RUSTUP": "/home/mystere/.cargo/bin/rustup"
  },
  "rust-analyzer.runnables.extraEnv": {
    "CARGO": "/home/mystere/.cargo/bin/cargo",
    "RUSTUP": "/home/mystere/.cargo/bin/rustup"
  },
  "rust-analyzer.server.extraEnv": {
    "CARGO": "/home/mystere/.cargo/bin/cargo",
    "RUSTUP": "/home/mystere/.cargo/bin/rustup"
  },
  "rust-analyzer.check.extraEnv": {
    "CARGO": "/home/mystere/.cargo/bin/cargo",
    "RUSTUP": "/home/mystere/.cargo/bin/rustup"
  }
}

こんなことをする羽目になった理由

VSCode と rust-analyzer を使って Rust で人道的に遊びたかったから。

セットアップは済んでいるので、Rust ファイルを開いたら以下の画像の要領でインレイ実行ボタンが出てきた。もちろん押してみた。そしたら Path to shell executable "cargo" does not exist と言われてしまった。もちろん端末では cargo はふっつーに動くので、これは rust-analyzer の怠慢であり偽情報である。

rust-analyzer についてこのインレイ実行ボタンの仕様がどこにも載ってないようなのでドキュメント不足を嘆いたところであるが、思うにこれは /bin/sh 上で動かしている上に中途半端な $PATH しか読んでない(.profile 固有の $PATH を多分読んでない?)からであろう。ユーザー環境で実行するんだからユーザー環境のプロファイルは全部読んでくれよ。

よってこれも推測に基づいた対策でしかないが、調べによると rust-analyzer に cargo と rustup の居場所を伝えてやれば良いらしかった。その方法が冒頭の記述である。もちろん rust-analyzer は無駄にセキュリティを重点しているようで、環境変数の類を指定すると LSP サーバー自体がバグって自滅するといった始末である。

残る謎

これは極めてあほなエラーであるので、おそらく開発側でとっくに対処されていそうなものである。しかし、調べによるとその形跡はまるでない。その割に同じようなエラー報告は2023年頃から散見される(どれもユーザー側の対処によって解決している)ので昔からあるエラーではあるようだ。

私の環境で特異な点といえば、VSCode を Remote-SSH 環境上で実行していることぐらいである。あんまり深掘りはしていないが、多分 Remote-SSH だと非ログインシェルだかが実行されることで .profile を都度読んでくれない。これが真因のように思えた。結局のところ、rust-analyzer が インレイ実行の際に コードを /bin/bash -l で実行してくれれば済む話である。

Discussion

ARGIAARGIA

rust-analyzer を散々貶してますけど、例えば以下のような設定を突っ込むと添付画像みたいに変なエラーを吐き出すので一体なんなのって言いたくもなりました。

  "rust-analyzer.server.extraEnv": {
    "PATH": "$PATH:$HOME/.cargo/bin",
    "CARGO": "$HOME/.cargo/bin/cargo",
    "RUSTUP": "$HOME/.cargo/bin/rustup"
  },

エラーでぼやいてるコマンドは以下の通りなんですけど、VSCode 上の端末だとエラー無く実行可能なので、やっぱり rust-analyzer の環境変数の取り扱いがあんまり直感的ではないのが悪そう。

cd "/home/mystere/devel/rust-otp" && CARGO="/home/mystere/.cargo/bin/cargo" RUSTUP="/home/mystere/.cargo/bin/rustup" RUSTUP_TOOLCHAIN="/home/mystere/.rustup/toolchains/stable-x86_64-unknown-linux-gnu" "$HOME/.cargo/bin/cargo" "check" "--workspace" "--message-format=json-diagnostic-rendered-ansi" "--manifest-path" "/home/mystere/devel/rust-otp/Cargo.toml" "--keep-going" "--all-targets"