できない.dev

Rust で「failed to resolve: use of undeclared crate or module」(E0433) が解決できない

名前解決の段階で、その名前のクレートやモジュールが見つからないという指摘。
外部クレートなら Cargo.toml への追加漏れ、自作モジュールなら mod 宣言の書き忘れが原因の大半で、どちらなのかを先に切り分けると早い。

公開:

要約

E0433 は型エラーではなく 名前解決 のエラーです。
コンパイラーは「この名前に対応するクレートもモジュールも、いま見えている範囲に無い」と言っています。

見えている範囲を決めるのは 2 つだけです。
外部クレートなら Cargo.toml[dependencies]、自作コードなら mod 宣言によるモジュールツリーへの接続です。
どちらの話なのかを最初に決めれば、直し方は一つに定まります。

綴りが合っているのに出る場合は、ほぼ後者の接続漏れです。

よくある原因

  1. 依存を書かずに use している。
    サンプルコードを貼り付けたときの定番で、cargo add を忘れています。
  2. ファイルは作ったが mod を書いていない。
    Rust はディレクトリを走査してモジュールを自動登録しません。
    親から mod で明示的に接続する必要があります。
  3. クレート名のハイフンをそのまま書いている。
    パッケージ名 serde-json は、コード上の識別子としては serde_json になります。
  4. ワークスペースの別クレートを参照している。
    同じリポジトリにあっても、依存として宣言していなければ他人のクレートと同じ扱いです。

解決策

1. 外部クレートなら依存を追加する

cargo add serde_json

Cargo.toml には次の行が入ります。
手で書いても構いませんが、cargo add はバージョンを調べて入れてくれるぶん確実です。

[dependencies]
serde_json = "1"

追加したら cargo build をやり直します。
エディターの表示が更新されない場合は rust-analyzer の再読み込みが必要なことがありますが、コンパイル自体はこれで通ります。

2. 自作モジュールは mod で接続する

src/utils.rs を作っただけでは、まだどこからも見えていません。
親(src/main.rssrc/lib.rs)に宣言を書きます。

// src/main.rs
mod utils;              // これが無いと utils::helper は E0433 になる
 
fn main() {
    utils::helper();
}

ディレクトリで区切る場合は、src/utils/mod.rs(または src/utils.rs)が子モジュールをまとめる役になり、その中でさらに mod を書きます。

// src/utils/mod.rs
pub mod text;
pub mod path;

3. ハイフンとアンダースコアの読み替え

Cargo.toml に書くパッケージ名と、コードで使う識別子は表記が違います。

[dependencies]
serde-json = "1"     # ハイフンでも受け付けられる
use serde_json::Value;   // コード側は必ずアンダースコア

エラーメッセージのクレート名がハイフン付きになっていたら、この読み替え漏れを疑ってください。

4. ワークスペースの別クレートを参照する

同一ワークスペースでも、依存の宣言は必要です。

[dependencies]
my-core = { path = "../my-core" }

5. 似たエラーと取り違えない

use of undeclared type や「そのモジュールにその名前が無い」(E0432) は別の問題です。
E0433 は入口となるクレート・モジュール自体が見つからない状態を指すので、use の 1 つ目の要素に注目して切り分けてください。

この記事は役立ちましたか?