An ability to inherit reason of #[must_use] (not whether it is #[must_use]).
If there is no #[must_use] to inherit, it errors.
Motivation
Side note: I know there are other cases that #[must_use] gets triggered without putting #[must_use] on the function, but will mention only return types for briefness.
There is a clippy lint double_must_use, warn by default.
The lint warns:
#[must_use] // warning!
fn f() -> Result<Thing, ()> {
todo!()
}
The point of the above is:
Result<T, E>is already marked as#[must_use]with some message.fis marked as#[must_use], with no message.- 1 and 2 are reported as separate diagnostic and
#[must_use]onfis less informative, therefore#[must_use]onfshould be removed.
It seems reasonable, but my concern is:
// Someday `Result<T, E>` became no longer needed, so got back to just `T`
// But I forgot to put `#[must_use]` again!
fn f() -> Thing {
todo!()
}
I found that what we want is "propagate the #[must_use] message", not "let's delegate whether the function is #[must_use], to the return type".
Does removing #[must_use] from fn f() -> Result<Thing, ()> mean the return value no longer must be used? No. It still must be used, but messages are taken from the return type. Explicit #[must_use = inherit] reflects this semantic well.
Additionally Needed Change
- 1 and 2 are reported as separate diagnostic and ...
We need to change this behavior to emit single warning, before introducing this feature. If we leave it as it is, the output will be quite confusing as warnings will get doubled. I'm considering to make #[must_use] on a function to override #[must_use] on the return type as it seems rational behavior, but it is problematic because it removes relatively more informative messages, not just confusing users a bit. Maybe we could make #[must_use = inherit] the default behavior for #[must_use], but I'm not sure if it is a breaking change.