Skip to content
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
147 changes: 118 additions & 29 deletions src/attributes/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,121 @@ r[attributes.codegen]

The following [attributes] are used for controlling code generation.

r[attributes.codegen.hint]
## Optimization hints

r[attributes.codegen.hint.cold-inline]
The `cold` and `inline` [attributes] give suggestions to generate code in a
way that may be faster than what it would do without the hint. The attributes
are only hints, and may be ignored.

r[attributes.codegen.hint.usage]
Both attributes can be used on [functions]. When applied to a function in a
[trait], they apply only to that function when used as a default function for
a trait implementation and not to all trait implementations. The attributes
have no effect on a trait function without a body.

<!-- template:attributes -->
r[attributes.codegen.inline]
### The `inline` attribute

r[attributes.codegen.inline.intro]
The *`inline` [attribute]* suggests that a copy of the attributed function
should be placed in the caller, rather than generating code to call the
function where it is defined.
The *`inline` [attribute]* suggests whether a copy of the attributed function's code should be placed in the caller rather than generating a call to the function.

> [!EXAMPLE]
> ```rust
> #[inline]
> pub fn example1() {}
>
> #[inline(always)]
> pub fn example2() {}
>
> #[inline(never)]
> pub fn example3() {}
> ```

> [!NOTE]
> `rustc` automatically inlines functions when doing so seems worthwhile. Use this attribute carefully as poor decisions about what to inline can slow down programs.

r[attributes.codegen.inline.syntax]
The syntax for the `inline` attribute is:

```grammar,attributes
@root InlineAttribute ->
`inline` `(` `always` `)`
| `inline` `(` `never` `)`
| `inline`
```

r[attributes.codegen.inline.allowed-positions]
The `inline` attribute may only be applied to functions with [bodies] --- [closures], [async blocks], [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition] .

> [!NOTE]
> The `rustc` compiler automatically inlines functions based on internal heuristics. Incorrectly inlining functions can make the program slower, so this attribute should be used with care.
> `rustc` ignores use in other positions but lints against it. This may become an error in the future.

> [!NOTE]
> Though the attribute can be applied to [closures] and [async blocks], the usefulness of this is limited as we do not yet support attributes on expressions.
>
> ```rust
> // We allow attributes on statements.
> #[inline] || (); // OK
> #[inline] async {}; // OK
> ```
>
> ```rust,compile_fail,E0658
> // We don't yet allow attributes on expressions.
> let f = #[inline] || (); // ERROR
> ```

r[attributes.codegen.inline.duplicates]
Only the first use of `inline` on a function has effect.

> [!NOTE]
> `rustc` lints against any use following the first. This may become an error in the future.

r[attributes.codegen.inline.modes]
There are three ways to use the inline attribute:
The `inline` attribute supports these modes:

* `#[inline]` *suggests* performing an inline expansion.
* `#[inline(always)]` *suggests* that an inline expansion should always be
performed.
* `#[inline(never)]` *suggests* that an inline expansion should never be
performed.
- `#[inline]` *suggests* performing inline expansion.
- `#[inline(always)]` *suggests* that inline expansion should always be performed.
- `#[inline(never)]` *suggests* that inline expansion should never be performed.

> [!NOTE]
> `#[inline]` in every form is a hint, with no *requirements* on the language to place a copy of the attributed function in the caller.
> In every form the attribute is a hint. The compiler may ignore it.

r[attributes.codegen.inline.trait]
When `inline` is applied to a function in a [trait], it applies only to the code of the [default definition].

r[attributes.codegen.inline.async]
When `inline` is applied to an [async function] or [async closure], it applies only to the code of the generated `poll` function.

> [!NOTE]
> For more details, see [Rust issue #129347](https://github.com/rust-lang/rust/issues/129347).

r[attributes.codegen.inline.externally-exported]
The `inline` attribute is ignored if the function is externally exported with [`no_mangle`] or [`export_name`].

<!-- template:attributes -->
r[attributes.codegen.cold]
### The `cold` attribute

The *`cold` [attribute]* suggests that the attributed function is unlikely to
be called.
r[attributes.codegen.cold.intro]
The *`cold` [attribute]* suggests that the attributed function is unlikely to be called which may help the compiler produce better code.

> [!EXAMPLE]
> ```rust
> #[cold]
> pub fn example() {}
> ```

r[attributes.codegen.cold.syntax]
The `cold` attribute uses the [MetaWord] syntax.

r[attributes.codegen.cold.allowed-positions]
The `cold` attribute may only be applied to functions with [bodies] --- [closures], [async blocks], [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition] .

> [!NOTE]
> `rustc` ignores use in other positions but lints against it. This may become an error in the future.

> [!NOTE]
> Though the attribute can be applied to [closures] and [async blocks], the usefulness of this is limited as we do not yet support attributes on expressions.

<!-- TODO: rustc currently seems to allow cold on a trait function without a body, but it appears to be ignored. I think that may be a bug, and it should at least warn if not reject (like inline does). -->

r[attributes.codegen.cold.duplicates]
Only the first use of `cold` on a function has effect.

> [!NOTE]
> `rustc` lints against any use following the first. This may become an error in the future.

r[attributes.codegen.cold.trait]
When `cold` is applied to a function in a [trait], it applies only to the code of the [default definition].

r[attributes.codegen.naked]
## The `naked` attribute
Expand Down Expand Up @@ -655,11 +728,14 @@ r[attributes.codegen.instruction_set.syntax]
The `instruction_set` attribute uses the [MetaListPaths] syntax to specify a single path consisting of the architecture family name and instruction set name.

r[attributes.codegen.instruction_set.allowed-positions]
The `instruction_set` attribute may only be applied to functions, including [closures][expr.closure], [free functions][items.fn], and associated functions defined (i.e. with a body) in [inherent impls][items.associated.fn], [trait impls][items.impl.trait], and [trait definitions][items.traits].
The `instruction_set` attribute may only be applied to functions with [bodies] --- [closures], [async blocks], [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition] .

> [!NOTE]
> `rustc` ignores use in other positions but lints against it. This may become an error in the future.

> [!NOTE]
> Though the attribute can be applied to [closures] and [async blocks], the usefulness of this is limited as we do not yet support attributes on expressions.

r[attributes.codegen.instruction_set.duplicates]
The `instruction_set` attribute may be used only once on a function.

Expand All @@ -684,18 +760,31 @@ If the address of the function is taken as a function pointer, the low bit of th

[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu
[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature
[`export_name`]: abi.export_name
[`is_aarch64_feature_detected`]: ../../std/arch/macro.is_aarch64_feature_detected.html
[`is_x86_feature_detected`]: ../../std/arch/macro.is_x86_feature_detected.html
[`Location`]: core::panic::Location
[`naked_asm!`]: ../inline-assembly.md
[`no_mangle`]: abi.no_mangle
[`target_feature` conditional compilation option]: ../conditional-compilation.md#target_feature
[`unused_variables`]: ../../rustc/lints/listing/warn-by-default.html#unused-variables
[associated functions]: items.associated.fn
[async blocks]: expr.block.async
[async closure]: expr.closure.async
[async function]: items.fn.async
[attribute]: ../attributes.md
[attributes]: ../attributes.md
[bodies]: items.fn.body
[closures]: expr.closure
[default definition]: items.traits.associated-item-decls
[free functions]: items.fn
[function body]: ../items/functions.md#function-body
[functions]: ../items/functions.md
[inherent impl]: items.impl.inherent
[rust-abi]: ../items/external-blocks.md#abi
[target architecture]: ../conditional-compilation.md#target_arch
[trait]: ../items/traits.md
[trait]: items.traits
[trait definition]: items.traits
[trait impl]: items.impl.trait
[undefined behavior]: ../behavior-considered-undefined.md
[unsafe attribute]: ../attributes.md#r-attributes.safety
29 changes: 20 additions & 9 deletions src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,21 @@ fn documented() {
> Except for lints, it is idiomatic to only use outer attributes on function items.

r[items.fn.attributes.builtin-attributes]
The attributes that have meaning on a function are [`cfg`], [`cfg_attr`], [`deprecated`],
[`doc`], [`export_name`], [`link_section`], [`no_mangle`], [the lint check
attributes], [`must_use`], [the procedural macro attributes], [the testing
attributes], and [the optimization hint attributes]. Functions also accept
attributes macros.
The attributes that have meaning on a function are:

- [`cfg_attr`]
- [`cfg`]
- [`cold`]
- [`deprecated`]
- [`doc`]
- [`export_name`]
- [`inline`]
- [`link_section`]
- [`must_use`]
- [`no_mangle`]
- [Lint check attributes]
- [Procedural macro attributes]
- [Testing attributes]

r[items.fn.param-attributes]
## Attributes on function parameters
Expand Down Expand Up @@ -471,10 +481,11 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
[attributes]: ../attributes.md
[`cfg`]: ../conditional-compilation.md#the-cfg-attribute
[`cfg_attr`]: ../conditional-compilation.md#the-cfg_attr-attribute
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
[the procedural macro attributes]: ../procedural-macros.md
[the testing attributes]: ../attributes/testing.md
[the optimization hint attributes]: ../attributes/codegen.md#optimization-hints
[lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
[procedural macro attributes]: ../procedural-macros.md#attribute-macros
[testing attributes]: ../attributes/testing.md
[`cold`]: ../attributes/codegen.md#the-cold-attribute
[`inline`]: ../attributes/codegen.md#the-inline-attribute
[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute
[`doc`]: ../../rustdoc/the-doc-attribute.html
[`must_use`]: ../attributes/diagnostics.md#the-must_use-attribute
Expand Down