Rust nightly で rls 等がインストールできないときの対策

Rust は将来導入が検討されている機能も nightly チャンネルとしてリリースされているので、簡単に試せるのは良いのですが、コンパイラ本体である rustc 以外の周辺ツールが壊れてしまうような変更もちょくちょく入ったりするので、タイミングによっては visual studio codeプラグインがまともに動けなくて辛いことがあります。

例えば、昨年末は rls が壊されていたので、VScodeプラグインはこんなエラーを吐いていました。

> Executing task: rustup component add rls --toolchain nightly-x86_64-unknown-linux-gnu <

error: component 'rls' for target 'x86_64-unknown-linux-gnu' is unavailable for download for channel 'nightly'
Sometimes not all components are available in any given nightly. If you don't need the component, you can remove it with:

    rustup component remove --toolchain nightly --target x86_64-unknown-linux-gnu rls

そんなときは、壊れていない少し過去のバージョンを明示的に指定して使うように設定すれば回避が可能です。

壊れていないバージョンを見つける

nightly の、どのバージョンでどのツールが壊れているかは、下記サイトで確認できます。

rust-lang.github.io

missing と表示されているのが壊れているバージョンです。必要なツールすべてが present になっているバージョンを見つけて、それを使用すれば良い、ということになります。(昨年末は、12月中ほぼずっと rls が壊れていて、表の表示範囲を超えてしまっていましたが、そんなときでも、右端の Last available を見れば最後に大丈夫だったバージョンを確認できます。)

なお、上記サイトは、どうやら、アクセス元のブラウザを見て表示するターゲット環境を選択しているようです。もし、ページ上部に x86_64-unknown-linux-gnu などと表示されているターゲットが自分のほしいものでなければ、ページ中程の Other targets でページを切り替える必要があります。(自分が使っているホスト環境の target triple は rustup show で表示できます。)

また、スクリプト等で自動処理をさせることを考えるなら、以下のようにダイレクトに情報取得する方法もあります。

$ curl https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/rls
2021-12-05

固定バージョンを使用するように指定する

使えるバージョンがみつかったら、次は、それを固定で使用するように rust 環境を設定します。これにはいくつかの方法があります。

指定方法1:rust-toolchain.toml ファイルを作成

プロジェクトのホームである Cargo.toml などが置かれているディレクトrust-toolchain.toml というファイルを作成し、そこに下記のようにバージョン指定を書けば、そのプロジェクトでだけ指定バージョンが使用されるようになります。

[toolchain]
channel = "nightly-2021-12-05"

なお、rust-toolchain(拡張子なし) というファイルに nightly-2021-12-05 とだけ書く方法もありますが、これは互換性のために残してある旧式の指定方法なので、新しく作るなら toml で書いておいたほうが良いかなと思います。(github actions の actions-rs/toolchain が現状まだ対応できていなかったり など、未対応な周辺システムもあるので、それに依存しているなら旧式でも構わないとは思いますが)

指定方法2:rustup override を使用する

rustup の設定で override を指定すれば、rust-toolchain ファイルと同様、そのディレクトリでのみツールチェインを変更できます。この設定は ~/.rustup/settings.toml に保存され、あなたの rustup 環境でのみ有効です。ファイルを別ディレクトリにコピーしたり、別のユーザーがビルドしようとした場合には効きません。

$ rustup override set nightly-2021-12-05

現在の設定値は rustup override list で確認でき、rustup override unset で設定を削除できます。

指定方法3: VScode で設定する

VScode 側で設定するなら、 settings.json に下記のような設定を追加する方法もあります。(VScode の他の設定と同様、ユーザー設定に書くか、ワークスペース設定に書くかで、どの範囲で有効になるのかが変わります)

"rust-client.channel": "nightly-2021-12-05"

指定方法4: デフォルトのツールチェインを変更

俺は rust は nightly しか使わん! というロックな人なら default を変更する手もあります。

$ rustup default nightly-2021-12-05

が、普通の人はやめておいた方がよいです。通常の安定版に戻すなら

$ rustup default stable

結局どの方法で指定すれば良い?

個人的な推奨設定は、nightly でしか動かないコードを書いているなら、

  • 普段はそのプロジェクトの rust-toolchain.toml を nightly と細かいバージョン指定無しで設定しておく
  • rlsが無いなどの一時的な理由で nightly のバージョンを固定したいときは rustup override で一時的に上書き固定設定する(壊れが解消されたら rustup override unset で設定を消す)

という運用が良いかと思います。(両方に設定されていた場合、 rust-toolchain よりも override の方が優先されます。)

参考

https://qiita.com/skitoy4321/items/0bf6826f948720bed821 https://qiita.com/s4i/items/0538f7fe4874980ccf27 https://qiita.com/tatsuya6502/items/8b31e2b162aff78787fe https://rust-lang.github.io/rustup/overrides.html

近況

最近、過去に一度調べて理解したはずなのに、再度使用しようとしてうまくできなくて困る、ということが多発しているので(もうトシか……)、再度ここを備忘録として活用してみようと思います。