Skip to content

Update must_use to use the attribute template #1892

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 84 additions & 65 deletions src/attributes/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,86 +349,105 @@ r[attributes.diagnostics.must_use]
## The `must_use` attribute

r[attributes.diagnostics.must_use.intro]
The *`must_use` attribute* is used to issue a diagnostic warning when a value
is not "used".
The *`must_use` [attribute][attributes]* is used to issue a diagnostic warning when a value is not used.

r[attributes.diagnostics.must_use.allowed-positions]
The `must_use` attribute can be applied to user-defined composite types
([`struct`s][struct], [`enum`s][enum], and [`union`s][union]), [functions],
and [traits].
r[attributes.diagnostics.must_use.syntax]
The `must_use` attribute uses either the [MetaWord] syntax or the [MetaNameValueStr] syntax to be able to [specify a message][attributes.diagnostics.must_use.message].

r[attributes.diagnostics.must_use.message]
The `must_use` attribute may include a message by using the
[MetaNameValueStr] syntax such as `#[must_use = "example message"]`. The
message will be given alongside the warning.
> [!EXAMPLE]
> ```rust
> #[must_use]
> fn use_me() -> u8 { 0 }
>
> #[must_use = "explanation of why it must be used"]
> fn use_me2() -> u8 { 0 }
> ```

r[attributes.diagnostics.must_use.type]
When used on user-defined composite types, if the [expression] of an
[expression statement] has that type, then the `unused_must_use` lint is
violated.
r[attributes.diagnostics.must_use.allowed-positions]
The `must_use` attribute may be applied to a:

```rust
#[must_use]
struct MustUse {
// some fields
}
- [Struct]
- [Enumeration]
- [Union]
- [Function]
- [Trait]

# impl MustUse {
# fn new() -> MustUse { MustUse {} }
# }
#
// Violates the `unused_must_use` lint.
MustUse::new();
```
> [!NOTE]
> `rustc` currently warns in other positions, but this may be rejected in the future.

r[attributes.diagnostics.must_use.fn]
When used on a function, if the [expression] of an [expression statement] is a
[call expression] to that function, then the `unused_must_use` lint is
violated.
r[attributes.diagnostics.must_use.duplicates]
The `must_use` attribute may only be specified once on an item.

```rust
#[must_use]
fn five() -> i32 { 5i32 }
> [!NOTE]
> `rustc` currently warns on subsequent duplicate `must_use` attributes. This may become an error in the future.

// Violates the unused_must_use lint.
five();
```
r[attributes.diagnostics.must_use.message]
The `must_use` attribute may include a message by using the [MetaNameValueStr] syntax such as `#[must_use = "example message"]`. The message will be given alongside the warning.

r[attributes.diagnostics.must_use.trait]
When used on a [trait declaration], a [call expression] of an [expression
statement] to a function that returns an [impl trait] or a [dyn trait] of that trait violates
the `unused_must_use` lint.
r[attributes.diagnostics.must_use.type]
When used on user-defined composite types, if the [expression] of an [expression statement] has that type, then the `unused_must_use` lint is violated.

```rust
#[must_use]
trait Critical {}
impl Critical for i32 {}
> [!EXAMPLE]
> ```rust
> #[must_use]
> struct MustUse {
> // some fields
> }
>
> # impl MustUse {
> # fn new() -> MustUse { MustUse {} }
> # }
> #
> // Violates the `unused_must_use` lint.
> MustUse::new();
> ```

fn get_critical() -> impl Critical {
4i32
}
r[attributes.diagnostics.must_use.fn]
When used on a function, if the [expression] of an [expression statement] is a [call expression] to that function, then the `unused_must_use` lint is violated.

// Violates the `unused_must_use` lint.
get_critical();
```
> [!EXAMPLE]
> ```rust
> #[must_use]
> fn five() -> i32 { 5i32 }
>
> // Violates the unused_must_use lint.
> five();
> ```

r[attributes.diagnostics.must_use.trait-function]
When used on a function in a trait declaration, then the behavior also applies
when the call expression is a function from an implementation of the trait.
r[attributes.diagnostics.must_use.trait]
When used on a [trait declaration], a [call expression] of an [expression statement] to a function that returns an [impl trait] or a [dyn trait] of that trait violates the `unused_must_use` lint.

```rust
trait Trait {
#[must_use]
fn use_me(&self) -> i32;
}
> [!EXAMPLE]
> ```rust
> #[must_use]
> trait Critical {}
> impl Critical for i32 {}
>
> fn get_critical() -> impl Critical {
> 4i32
> }
>
> // Violates the `unused_must_use` lint.
> get_critical();
> ```

impl Trait for i32 {
fn use_me(&self) -> i32 { 0i32 }
}
r[attributes.diagnostics.must_use.trait-function]
When used on a function in a trait declaration, then the behavior also applies when the call expression is a function from an implementation of the trait.

// Violates the `unused_must_use` lint.
5i32.use_me();
```
> [!EXAMPLE]
> ```rust
> trait Trait {
> #[must_use]
> fn use_me(&self) -> i32;
> }
>
> impl Trait for i32 {
> fn use_me(&self) -> i32 { 0i32 }
> }
>
> // Violates the `unused_must_use` lint.
> 5i32.use_me();
> ```

r[attributes.diagnostics.must_use.trait-impl-function]
When used on a function in a trait implementation, the attribute does nothing.
Expand Down Expand Up @@ -669,7 +688,7 @@ The first error message includes a somewhat confusing error message about the re
[call expression]: ../expressions/call-expr.md
[dyn trait]: ../types/trait-object.md
[enum variant]: ../items/enumerations.md
[enum]: ../items/enumerations.md
[enumeration]: ../items/enumerations.md
[expression statement]: ../statements.md#expression-statements
[expression]: ../expressions.md
[external block item]: ../items/external-blocks.md
Expand Down