Rust で「failed to resolve: use of undeclared crate or module」(E0433) が解決できない
名前解決の段階で、その名前のクレートやモジュールが見つからないという指摘。
外部クレートなら Cargo.toml への追加漏れ、自作モジュールなら mod 宣言の書き忘れが原因の大半で、どちらなのかを先に切り分けると早い。
公開:
要約
E0433 は型エラーではなく 名前解決 のエラーです。
コンパイラーは「この名前に対応するクレートもモジュールも、いま見えている範囲に無い」と言っています。
見えている範囲を決めるのは 2 つだけです。
外部クレートなら Cargo.toml の [dependencies]、自作コードなら mod 宣言によるモジュールツリーへの接続です。
どちらの話なのかを最初に決めれば、直し方は一つに定まります。
綴りが合っているのに出る場合は、ほぼ後者の接続漏れです。
よくある原因
- 依存を書かずに
useしている。
サンプルコードを貼り付けたときの定番で、cargo addを忘れています。 - ファイルは作ったが
modを書いていない。
Rust はディレクトリを走査してモジュールを自動登録しません。
親からmodで明示的に接続する必要があります。 - クレート名のハイフンをそのまま書いている。
パッケージ名serde-jsonは、コード上の識別子としてはserde_jsonになります。 - ワークスペースの別クレートを参照している。
同じリポジトリにあっても、依存として宣言していなければ他人のクレートと同じ扱いです。
解決策
1. 外部クレートなら依存を追加する
cargo add serde_jsonCargo.toml には次の行が入ります。
手で書いても構いませんが、cargo add はバージョンを調べて入れてくれるぶん確実です。
[dependencies]
serde_json = "1"追加したら cargo build をやり直します。
エディターの表示が更新されない場合は rust-analyzer の再読み込みが必要なことがありますが、コンパイル自体はこれで通ります。
2. 自作モジュールは mod で接続する
src/utils.rs を作っただけでは、まだどこからも見えていません。
親(src/main.rs か src/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 つ目の要素に注目して切り分けてください。