Skip to content

Commit 93fe20d

Browse files
committed
Revise must_use attribute text
Let's adjust the section on `must_use` to follow the editorial direction we've been taking.
1 parent 106a4a1 commit 93fe20d

1 file changed

Lines changed: 90 additions & 71 deletions

File tree

src/attributes/diagnostics.md

Lines changed: 90 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -350,17 +350,17 @@ r[attributes.diagnostics.must_use]
350350
## The `must_use` attribute
351351

352352
r[attributes.diagnostics.must_use.intro]
353-
The *`must_use` [attribute][attributes]* is used to issue a diagnostic warning when a value is not used.
353+
The *`must_use` [attribute]* marks a value that should be used.
354354

355355
r[attributes.diagnostics.must_use.syntax]
356-
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].
356+
The `must_use` attribute uses the [MetaWord] and [MetaNameValueStr] syntaxes.
357357

358358
> [!EXAMPLE]
359359
> ```rust
360360
> #[must_use]
361-
> fn use_me() -> u8 { 0 }
361+
> fn use_me1() -> u8 { 0 }
362362
>
363-
> #[must_use = "explanation of why it must be used"]
363+
> #[must_use = "explanation of why it should be used"]
364364
> fn use_me2() -> u8 { 0 }
365365
> ```
366366
@@ -383,102 +383,118 @@ The `must_use` attribute may be used only once on an item.
383383
> `rustc` lints against any use following the first. This may become an error in the future.
384384
385385
r[attributes.diagnostics.must_use.message]
386-
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.
386+
The `must_use` attribute may include a message by using the [MetaNameValueStr] syntax, e.g., `#[must_use = "example message"]`. The message may be emitted as part of the lint.
387387
388388
r[attributes.diagnostics.must_use.type]
389-
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.
389+
When the attribute is applied to a [struct], [enumeration], or [union], if the [expression] of an [expression statement] has that type, the use triggers the `unused_must_use` lint.
390390
391-
> [!EXAMPLE]
392-
> ```rust
393-
> #[must_use]
394-
> struct MustUse {
395-
> // some fields
396-
> }
397-
>
398-
> # impl MustUse {
399-
> # fn new() -> MustUse { MustUse {} }
400-
> # }
401-
> #
402-
> // Violates the `unused_must_use` lint.
403-
> MustUse::new();
404-
> ```
391+
```rust,compile_fail
392+
#![deny(unused_must_use)]
393+
#[must_use]
394+
struct MustUse();
395+
MustUse(); // ERROR: Unused value that must be used.
396+
```
405397
406398
r[attributes.diagnostics.must_use.fn]
407-
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.
399+
If the [expression] of an [expression statement] is a [call expression] or [method call expression] whose function operand is a function to which the attribute is applied, the use triggers the `unused_must_use` lint.
408400

409-
> [!EXAMPLE]
410-
> ```rust
411-
> #[must_use]
412-
> fn five() -> i32 { 5i32 }
413-
>
414-
> // Violates the unused_must_use lint.
415-
> five();
416-
> ```
401+
```rust,compile_fail
402+
#![deny(unused_must_use)]
403+
#[must_use]
404+
fn f() {}
405+
f(); // ERROR: Unused return value that must be used.
406+
```
417407

418408
r[attributes.diagnostics.must_use.trait]
419-
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.
409+
If the [expression] of an [expression statement] is a [call expression] or [method call expression] whose function operand is a function that returns an [impl trait] or a [dyn trait] type where one or more traits in the bound are marked with the attribute, the use triggers the `unused_must_use` lint.
420410

421-
> [!EXAMPLE]
422-
> ```rust
423-
> #[must_use]
424-
> trait Critical {}
425-
> impl Critical for i32 {}
426-
>
427-
> fn get_critical() -> impl Critical {
428-
> 4i32
429-
> }
430-
>
431-
> // Violates the `unused_must_use` lint.
432-
> get_critical();
433-
> ```
411+
```rust,compile_fail
412+
#![deny(unused_must_use)]
413+
#[must_use]
414+
trait Tr {}
415+
impl Tr for () {}
416+
fn f() -> impl Tr {}
417+
f(); // ERROR: Unused implementor that must be used.
418+
```
434419

435420
r[attributes.diagnostics.must_use.trait-function]
436-
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.
421+
When the attribute is applied to a function in a trait declaration, the rules described in [attributes.diagnostics.must_use.fn] also apply when the function operand of the [call expression] or [method call expression] is an implementation of that function.
437422

438-
> [!EXAMPLE]
439-
> ```rust
440-
> trait Trait {
441-
> #[must_use]
442-
> fn use_me(&self) -> i32;
443-
> }
444-
>
445-
> impl Trait for i32 {
446-
> fn use_me(&self) -> i32 { 0i32 }
447-
> }
448-
>
449-
> // Violates the `unused_must_use` lint.
450-
> 5i32.use_me();
451-
> ```
423+
```rust,compile_fail
424+
#![deny(unused_must_use)]
425+
trait Tr {
426+
#[must_use]
427+
fn use_me(&self);
428+
}
429+
430+
impl Tr for () {
431+
fn use_me(&self) {}
432+
}
433+
434+
().use_me(); // ERROR: Unused return value that must be used.
435+
```
436+
437+
```rust,compile_fail
438+
# #![deny(unused_must_use)]
439+
# trait Tr {
440+
# #[must_use]
441+
# fn use_me(&self);
442+
# }
443+
#
444+
# impl Tr for () {
445+
# fn use_me(&self) {}
446+
# }
447+
#
448+
<() as Tr>::use_me(&());
449+
// ^^^^^^^^^^^ ERROR: Unused return value that must be used.
450+
```
452451

453452
r[attributes.diagnostics.must_use.trait-impl-function]
454453
When used on a function in a trait implementation, the attribute does nothing.
455454

455+
```rust
456+
#![deny(unused_must_use)]
457+
trait Tr {
458+
fn f(&self);
459+
}
460+
461+
impl Tr for () {
462+
#[must_use] // This has no effect.
463+
fn f(&self) {}
464+
}
465+
466+
().f(); // OK.
467+
```
468+
456469
> [!NOTE]
457-
> Trivial no-op expressions containing the value will not violate the lint. Examples include wrapping the value in a type that does not implement [`Drop`] and then not using that type and being the final expression of a [block expression] that is not used.
470+
> `rustc` lints against use on functions in trait implementations. This may become an error in the future.
471+
472+
> [!NOTE]
473+
> Wrapping the value, even trivially, will suppress the lint.
458474
>
459475
> ```rust
476+
> #![deny(unused_must_use)]
460477
> #[must_use]
461-
> fn five() -> i32 { 5i32 }
478+
> fn f() {}
462479
>
463-
> // None of these violate the unused_must_use lint.
464-
> (five(),);
465-
> Some(five());
466-
> { five() };
467-
> if true { five() } else { 0i32 };
480+
> // None of these trigger the `unused_must_use` lint.
481+
> (f(),);
482+
> Some(f());
483+
> { f() };
484+
> if true { f() } else {};
468485
> match true {
469-
> _ => five()
486+
> _ => f()
470487
> };
471488
> ```
472489
473490
> [!NOTE]
474-
> It is idiomatic to use a [let statement] with a pattern of `_` when a must-used value is purposely discarded.
491+
> Using a [let statement] with a pattern of `_` when a must-used value is purposely discarded is idiomatic.
475492
>
476493
> ```rust
494+
> #![deny(unused_must_use)]
477495
> #[must_use]
478-
> fn five() -> i32 { 5i32 }
479-
>
480-
> // Does not violate the unused_must_use lint.
481-
> let _ = five();
496+
> fn f() {}
497+
> let _ = f(); // OK.
482498
> ```
483499
484500
r[attributes.diagnostic.namespace]
@@ -684,9 +700,11 @@ The first error message includes a somewhat confusing error message about the re
684700

685701
[Clippy]: https://github.com/rust-lang/rust-clippy
686702
[`Drop`]: ../special-types-and-traits.md#drop
703+
[attribute]: ../attributes.md
687704
[attributes]: ../attributes.md
688705
[block expression]: ../expressions/block-expr.md
689706
[call expression]: ../expressions/call-expr.md
707+
[method call expression]: ../expressions/method-call-expr.md
690708
[dyn trait]: ../types/trait-object.md
691709
[enum variant]: ../items/enumerations.md
692710
[enumeration]: ../items/enumerations.md
@@ -706,6 +724,7 @@ The first error message includes a somewhat confusing error message about the re
706724
[rustdoc]: ../../rustdoc/lints.html
707725
[struct field]: ../items/structs.md
708726
[struct]: ../items/structs.md
727+
[external block]: ../items/external-blocks.md
709728
[trait declaration]: ../items/traits.md
710729
[trait item]: ../items/traits.md
711730
[trait-impl]: ../items/implementations.md#trait-implementations

0 commit comments

Comments
 (0)