diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index b38b578312..8d7948163b 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -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. - + 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`]. + + 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. + + + +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 @@ -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. @@ -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 diff --git a/src/items/functions.md b/src/items/functions.md index e988077eb5..96bbc0b39b 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -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 @@ -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