🎃

(Rust初心者あるある)cargo updateを実行したのに依存が更新されない?

2024/02/11に公開

問題

「Rust初心者あるある」ではないかもしれませんが、その点はスルーしてください。

以下のcargoコマンドを実行して依存を追加したとします。

$ cargo new hello
$ cd hello
$ cargo add rand@0.8.4

※cargoコマンドはrustupを利用してインストールしたものです。拡張機能は追加していません。

Cargo.tomlファイルを確認すると、正しく依存が追加されています。

[dependencies]
rand = "0.8.4"

さて、randのバージョンとして0.8.4を指定しましたが、最新のバージョンは0.8.5です。cargo searchコマンドを実行して確認してみましょう。

$ cargo search rand
rand = "0.8.5"              # Random number generators and other randomness functionality.
bevy_rand = "0.4.0"         # A plugin to integrate rand for ECS optimised RNG for the Bevy game engine.
tinyrand = "0.5.0"          # Lightweight RNG specification and several ultrafast implementations in Rust.
...

それではcargo updateを実行してrandのバージョンを最新にしましょう。Updating rand v0.8.4 -> v0.8.5と表示されるはずです。

$ cargo update
    Updating crates.io index
$ 

何も表示されず終了しました!!!

意図しない挙動の原因

この挙動はバージョン指定方法の勘違いが原因です。0.8.4は完全一致を意味しません。

まず、0.8.4は先頭のキャレットを省略した気泡として解釈されます。バージョン指定の文字列0.8.4^0.8.4は同じものとして解釈されます。。

そして、^0.8.4は最新のマイナーバージョン(0.8.4以上0.9.0未満)を意味します。従って、cargo add rand@0.8.4を実行するとバージョン0.8.5がインストールされます。

一度helloディレクトリを削除して、改めて確認してみましょう。

$ cd ..
$ rm -rf hello
$ cargo new hello
$ cd hello
$ cargo add rand@0.8.4

Cargo.lockファイルを開いてください。このファイルにはインストール済みの依存関係が記録されています。以下の行を探してください。

[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"

このようにrandのバージョン0.8.5がインストールされていたため、cargo updateを実行しても期待した動作をしなかったのです。

cargo updateの再確認

依存関係のバージョンを完全一致で指定するには先頭に=をつけます。試してみましょう。

$ cd ..
$ rm -rf hello
$ cargo new hello
$ cd hello
$ cargo add rand@=0.8.4

Cargo.lockファイルを開いて確認してみましょう。インストール済みのバージョンとして0.8.4が記録されています。

[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"

それではCargo.tomlを変更しましょう。

# 変更前
[dependencies]
rand = "=0.8.4"

# 変更後
[dependencies]
rand = "0.8.4"

バージョン文字列の先頭から=を除去しました。これで最新のマイナーバージョンを使用せよ、という意味になります。

改めてcargo updateを実行してみましょう。

$ cargo update
    Updating crates.io index
    Updating rand v0.8.4 -> v0.8.5
    ...

期待どおりの挙動です。randのバージョンが0.8.4から0.8.5に更新されました。

参考資料

  1. Programming a Guessing Game - The Rust Programming Language

Discussion