Skip to content
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

Document RFC 1940 (must_use on fns) #247

Merged
merged 4 commits into from
May 3, 2018
Merged
Show file tree
Hide file tree
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
117 changes: 112 additions & 5 deletions src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ macro scope.
object file that this item's contents will be placed into.
- `no_mangle` - on any item, do not apply the standard name mangling. Set the
symbol for this item to its identifier.
- `must_use` - on structs and enums, will warn if a value of this type isn't used or
assigned to a variable. You may also include an optional message by using
`#[must_use = "message"]` which will be given alongside the warning.

### Deprecation

Expand Down Expand Up @@ -325,7 +322,7 @@ The lint checks supported by the compiler can be found via `rustc -W help`,
along with their default settings. [Compiler
plugins][unstable book plugin] can provide additional lint checks.

```rust,ignore
```rust
pub mod m1 {
// Missing documentation is ignored here
#[allow(missing_docs)]
Expand Down Expand Up @@ -366,7 +363,7 @@ pub mod m2{
This example shows how one can use `forbid` to disallow uses of `allow` for
that lint check:

```rust,ignore
```rust,compile_fail
#[forbid(missing_docs)]
pub mod m3 {
// Attempting to toggle warning signals an error here
Expand All @@ -376,6 +373,105 @@ pub mod m3 {
}
```

#### `must_use` Attribute

The `must_use` attribute can be used on user-defined composite types
([`struct`s][struct], [`enum`s][enum], and [`union`s][union]) and [functions].

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]
struct MustUse {
// some fields
}

# impl MustUse {
# fn new() -> MustUse { MustUse {} }
# }
#
fn main() {
// Violates the `unused_must_use` lint.
MustUse::new();
}
```

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. The exceptions to this is if the return type
of the function is `()`, `!`, or a [zero-variant enum], in which case the
attribute does nothing.

```rust
#[must_use]
fn five() -> i32 { 5i32 }

fn main() {
// Violates the unused_must_use lint.
five();
}
```

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.

```rust
trait Trait {
#[must_use]
fn use_me(&self) -> i32;
}

impl Trait for i32 {
fn use_me(&self) -> i32 { 0i32 }
}

fn main() {
// Violates the `unused_must_use` lint.
5i32.use_me();
}
```

When used on a function in an implementation, the attribute does nothing.

> Note: 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.
>
> ```rust
> #[must_use]
> fn five() -> i32 { 5i32 }
>
> fn main() {
> // None of these violate the unused_must_use lint.
> (five(),);
> Some(five());
> { five() };
> if true { five() } else { 0i32 };
> match true {
> _ => five()
> };
> }
> ```

> Note: It is idiomatic to use a [let statement] with a pattern of `_`
> when a must-used value is purposely discarded.
>
> ```rust
> #[must_use]
> fn five() -> i32 { 5i32 }
>
> fn main() {
> // Does not violate the unused_must_use lint.
> let _ = five();
> }
> ```

The `must_use` attribute may also include a message by using
`#[must_use = "message"]`. The message will be given alongside the warning.

### Inline attribute

The inline attribute suggests that the compiler should place a copy of
Expand Down Expand Up @@ -430,4 +526,15 @@ You can implement `derive` for your own type through [procedural macros].
[Doc comments]: comments.html#doc-comments
[The Rustdoc Book]: ../rustdoc/the-doc-attribute.html
[procedural macros]: procedural-macros.html
[struct]: items/structs.html
[enum]: items/enumerations.html
[union]: items/unions.html
[functions]: items/functions.html
[expression]: expressions.html
[expression statement]: statements.html#expression-statements
[call expression]: expressions/call-expr.html
[block expression]: expressions/block-expr.html
[`Drop`]: special-types-and-traits.html#drop
[let statement]: statements.html#let-statements
[unstable book plugin]: ../unstable-book/language-features/plugin.html#lint-plugins
[zero-variant enum]: enumerations.html#zero-variant-enums
2 changes: 1 addition & 1 deletion src/type-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Closures have no layout guarantees.

## Representations

All user-defined composite types (`struct`s, `enum`, and `union`s) have a
All user-defined composite types (`struct`s, `enum`s, and `union`s) have a
*representation* that specifies what the layout is for the type.

The possible representations for a type are the default representation, `C`, the
Expand Down