You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `must_use` attribute can be applied to user-defined composite types
357
-
([`struct`s][struct], [`enum`s][enum], and [`union`s][union]), [functions],
358
-
and [traits].
368
+
The `must_use` attributemaybeappliedtoa:
369
+
370
+
- [Struct]
371
+
- [Enumeration]
372
+
- [Union]
373
+
- [Function]
374
+
- [Trait]
375
+
376
+
> [!NOTE]
377
+
> `rustc` ignoresusein other positions but lints against it.This may become an error in the future.
378
+
379
+
r[attributes.diagnostics.must_use.duplicates]
380
+
The `must_use` attribute may be used only once on an item.
381
+
382
+
> [!NOTE]
383
+
> `rustc` lints against any use following the first.This may become an error in the future.
359
384
360
385
r[attributes.diagnostics.must_use.message]
361
-
The `must_use` attribute may include a message by using the
362
-
[MetaNameValueStr] syntax such as `#[must_use = "example message"]`. The
363
-
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.
364
387
365
388
r[attributes.diagnostics.must_use.type]
366
-
When used on user-defined composite types, if the [expression] of an
367
-
[expression statement] has that type, then the `unused_must_use` lint is
368
-
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.
369
390
370
-
```rust
391
+
```rust,compile_fail
392
+
#![deny(unused_must_use)]
371
393
#[must_use]
372
-
structMustUse {
373
-
// some fields
374
-
}
394
+
structMustUse();
395
+
MustUse(); // ERROR: Unused value that must be used.
As an exception to [attributes.diagnostics.must_use.type], the lint does not fire for `Result<(), E>` when `E` is [uninhabited] or for `ControlFlow<B, ()>` when `B` is [uninhabited]. A `#[non_exhaustive]` type from an external crate is not considered uninhabited for this purpose, because it may gain constructors in the future.
When used on a function, if the [expression] of an [expression statement] is a
386
-
[call expression] to that function, then the `unused_must_use` lint is
387
-
violated.
412
+
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.
388
413
389
-
```rust
414
+
```rust,compile_fail
415
+
#![deny(unused_must_use)]
390
416
#[must_use]
391
-
fnfive() ->i32 { 5i32 }
392
-
393
-
// Violates the unused_must_use lint.
394
-
five();
417
+
fn f() {}
418
+
f(); // ERROR: Unused return value that must be used.
395
419
```
396
420
397
421
r[attributes.diagnostics.must_use.trait]
398
-
When used on a [trait declaration], a [call expression] of an [expression
399
-
statement] to a function that returns an [impl trait] or a [dyn trait] of that trait violates
400
-
the `unused_must_use` lint.
422
+
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.
401
423
402
-
```rust
424
+
```rust,compile_fail
425
+
#![deny(unused_must_use)]
403
426
#[must_use]
404
-
traitCritical {}
405
-
implCriticalfori32 {}
406
-
407
-
fnget_critical() ->implCritical {
408
-
4i32
409
-
}
410
-
411
-
// Violates the `unused_must_use` lint.
412
-
get_critical();
427
+
trait Tr {}
428
+
impl Tr for () {}
429
+
fn f() -> impl Tr {}
430
+
f(); // ERROR: Unused implementor that must be used.
413
431
```
414
432
415
433
r[attributes.diagnostics.must_use.trait-function]
416
-
When used on a function in a trait declaration, then the behavior also applies
417
-
when the call expression is a function from an implementation of the trait.
434
+
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.
418
435
419
-
```rust
420
-
traitTrait {
436
+
```rust,compile_fail
437
+
#![deny(unused_must_use)]
438
+
trait Tr {
421
439
#[must_use]
422
-
fnuse_me(&self)->i32;
440
+
fn use_me(&self);
423
441
}
424
442
425
-
implTraitfori32 {
426
-
fnuse_me(&self) ->i32 { 0i32}
443
+
impl Tr for () {
444
+
fn use_me(&self) {}
427
445
}
428
446
429
-
// Violates the `unused_must_use` lint.
430
-
5i32.use_me();
447
+
().use_me(); // ERROR: Unused return value that must be used.
448
+
```
449
+
450
+
```rust,compile_fail
451
+
# #![deny(unused_must_use)]
452
+
# trait Tr {
453
+
# #[must_use]
454
+
# fn use_me(&self);
455
+
# }
456
+
#
457
+
# impl Tr for () {
458
+
# fn use_me(&self) {}
459
+
# }
460
+
#
461
+
<() as Tr>::use_me(&());
462
+
// ^^^^^^^^^^^ ERROR: Unused return value that must be used.
463
+
```
464
+
465
+
r[attributes.diagnostics.must_use.block-expr]
466
+
When checking the [expression] of an [expression statement] for [attributes.diagnostics.must_use.type], [attributes.diagnostics.must_use.fn], [attributes.diagnostics.must_use.trait], and [attributes.diagnostics.must_use.trait-function], the lint looks through [block expressions][block expression] (including [`unsafe` blocks] and [labeled block expressions]) to the trailing expression of each. This applies recursively for nested block expressions.
467
+
468
+
```rust,compile_fail
469
+
#![deny(unused_must_use)]
470
+
#[must_use]
471
+
fn f() {}
472
+
473
+
{ f() }; // ERROR: The lint looks through block expressions.
474
+
unsafe { f() }; // ERROR: The lint looks through `unsafe` blocks.
475
+
{ { f() } }; // ERROR: The lint looks through nested blocks.
When used on a function in a trait implementation, the attribute does nothing.
435
480
481
+
```rust
482
+
#![deny(unused_must_use)]
483
+
traitTr {
484
+
fnf(&self);
485
+
}
486
+
487
+
implTrfor () {
488
+
#[must_use] // This has no effect.
489
+
fnf(&self) {}
490
+
}
491
+
492
+
().f(); // OK.
493
+
```
494
+
436
495
> [!NOTE]
437
-
> 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.
496
+
> `rustc` lints against use on functions in trait implementations. This may become an error in the future.
> Wrapping the result of a `#[must_use]` function in certain expressions can suppress the [fn-based check][attributes.diagnostics.must_use.fn], because the [expression] of the [expression statement] is not a [call expression] or [method call expression] to a `#[must_use]` function. The [type-based check][attributes.diagnostics.must_use.type] still applies if the type of the overall expression is `#[must_use]`.
438
501
>
439
502
> ```rust
503
+
> #![deny(unused_must_use)]
440
504
> #[must_use]
441
-
> fnfive() ->i32 { 5i32}
505
+
> fnf() {}
442
506
>
443
-
> // None of these violate the unused_must_use lint.
444
-
> (five(),);
445
-
> Some(five());
446
-
> { five() };
447
-
> iftrue { five() } else { 0i32 };
448
-
> matchtrue {
449
-
> _=>five()
507
+
> // The fn-based check does not fire for any of these, because the
508
+
> // expression of the expression statement is not a call to a
509
+
> // `#[must_use]` function.
510
+
> (f(),); // Expression is a tuple, not a call.
511
+
> Some(f()); // Callee `Some` is not `#[must_use]`.
512
+
> iftrue { f() } else {}; // Expression is an `if`, not a call.
513
+
> matchtrue { // Expression is a `match`, not a call.
514
+
> _=>f()
450
515
> };
451
516
> ```
517
+
>
518
+
> ```rust,compile_fail
519
+
> #![deny(unused_must_use)]
520
+
> #[must_use]
521
+
> structMustUse;
522
+
> fng() ->MustUse { MustUse }
523
+
>
524
+
> // Despite the `if` expression not being a call, the type-based check
525
+
> // fires because the type of the expression is `MustUse`, which has
526
+
> // the `#[must_use]` attribute.
527
+
> iftrue { g() } else { MustUse }; // ERROR: Must be used.
0 commit comments