warning: unused return value of `x` that must be used
使用必須とマークされた値を無視した。
must_use
属性をアイテムに付加すると、値の使い忘れを防止してくれる。
なお、属性をトレイトの実装側の関数に適用した場合、無視される。
つまり、トレイト側の関数の指定が適用される。
警告のメッセージはカスタマイズできる。
#[must_use]
… デフォルトのメッセージ。
#[must_use = "message"]
… カスタムのメッセージ。
以下、デフォルトのメッセージによる警告の例。
fn main() {
must_use();
}
#[must_use]
fn must_use() -> i32 {
42
}
warning: unused return value of `must_use` that must be used --> src\main.rs:2:5 | 2 | must_use(); | ^^^^^^^^^^ | = note: `#[warn(unused_must_use)]` on by default help: use `let _ = ...` to ignore the resulting value | 2 | let _ = must_use(); | +++++++
全ての使い忘れが警告されるわけではない。
ブロックやタプルなどでラップされると検出できない。
例えば、以下は警告を出力しない。
fn main() {
{ must_use() };
}
#[must_use]
fn must_use() -> i32 {
42
}
must_use
を適用すべきアイテムには以下の特徴がある。
Result<T, E>
)
なお、Option::map
など、コールバック引数を持つ関数では、たとえ副作用を伴わない用法が多くても、常にそうとは限らないので、対象外とする傾向がある。
std
の状況
、上記の基準から外れたものも多い。
また、同系統のアイテムについての一貫性もない。
いくつかピックアップした調査結果…。
以下はどれも副作用なしのため、全て must_use
が期待される。
Box::new
|
〇 |
---|---|
Vec::new
|
〇 |
Rc::new
|
× |
以下はどれも副作用なしのため、全て must_use
が期待される。
slice::len
|
〇 |
---|---|
slice::is_empty
|
〇 |
Vec::len
|
× |
Vec::is_empty
|
× |
Weak::strong_count
|
〇 |
Weak::weak_count
|
〇 |
Rc::strong_count
|
× |
Rc::weak_count
|
× |
以下はどれもコールバックを伴うため、全て must_use
なしが期待される。
Option::map
|
× |
---|---|
Option::is_some_and
|
〇 |
以下は副作用なしだが must_use
なし。
Result::ok
|
× |
---|---|
Result::err
|
× |