Rustのspecial-module-nameに関するエラー

はじめに

この記事では、「Rustのclippyで指摘されたfound module declaration for lib.rs」について書いています。

Rustでプログラムを書いていた時clippyで指摘され、(もしかしたら「こんなの当然だよ」というレベルの話かもしれず恥ずかしくもあるのですが)その原因を調べたのが記事を書いたきっかけでした。

自分に向けた備忘録でもありますが、「同じような指摘を受け、理由が分からない」な人の一助になれば嬉しいです。

ワーニングが出た条件

環境は以下の通りです。

Rustのプロジェクトは以下の通りです。

sample
├ src
│  ├ main.rs
│  └ lib.rs
└ Cargo.toml

各コードについては、main.rsは

mod lib;

fn main() {
    lib::greet();
}

lib.rsは

pub fn greet() {
    println!("Hello, world!");
}

です。

ライブラリのgreet()を呼んでHello, world!を出力するという簡単な処理のプログラムです。

ワーニングの内容

このプロジェクトについてcargo clippyを行うと最初にも書いたワーニング文が出てきます。

より詳細には以下のような出力です。

warning: found module declaration for lib.rs
 --> src\main.rs:1:1
  |
1 | mod lib;
  | ^^^^^^^^
  |
  = note: `#[warn(special_module_name)]` on by default
  = note: lib.rs is the root of this crate's library target
  = help: to refer to it from other targets, use the library's name as the path

どうもライブラリのファイル名をlib.rsにしてることに対して怒られているようです。

更に色々調べると以下のページに答えがありました。

https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#special-module-name

Explanation Cargo recognizes lib.rs and main.rs as the root of a library or binary crate, so declaring > them as modules will lead to miscompilation of the crate unless configured explicitly.

To access a library from a binary target within the same crate, use your_crate_name:: as the path path instead of lib:::

つまり、lib.rsはクレートのルートとして認識する特別なものだから、これを使う場合、mod libのようにモジュールとして宣言すると、ミスコンパイルにつながる可能性があるから、という理由でワーニングになっているようです。

対応

案: クレートの名前を使って呼び出す

以下のようにクレートの名前を使えばワーニングは解消されます。

fn main() {
    // lib::greet();  // ワーニングが出る
    sample::greet();
}

案: ライブラリの名前をlib.rsから変える

lib.rsという名前なのが問題なので、違う名前に変えることでワーニングを解消できます。

おわりに

「Rustのclippyで指摘されたfound module declaration for lib.rs」について解説しました。

main.rslib.rsはRustでは特別な意味を持つ名前なので、安易に使うと思わぬワーニングが起きてしまうみたいなので今後は気を付けようと思います。