Skip to content

Commit b091a8a

Browse files
authored
Merge pull request #1907 from ehuss/cold-inline
Update `cold` and `inline` to use the attribute template
2 parents 3279c0e + 80afb2e commit b091a8a

File tree

2 files changed

+138
-38
lines changed

2 files changed

+138
-38
lines changed

src/attributes/codegen.md

Lines changed: 118 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,121 @@ r[attributes.codegen]
33

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

6-
r[attributes.codegen.hint]
7-
## Optimization hints
8-
9-
r[attributes.codegen.hint.cold-inline]
10-
The `cold` and `inline` [attributes] give suggestions to generate code in a
11-
way that may be faster than what it would do without the hint. The attributes
12-
are only hints, and may be ignored.
13-
14-
r[attributes.codegen.hint.usage]
15-
Both attributes can be used on [functions]. When applied to a function in a
16-
[trait], they apply only to that function when used as a default function for
17-
a trait implementation and not to all trait implementations. The attributes
18-
have no effect on a trait function without a body.
19-
6+
<!-- template:attributes -->
207
r[attributes.codegen.inline]
218
### The `inline` attribute
229

2310
r[attributes.codegen.inline.intro]
24-
The *`inline` [attribute]* suggests that a copy of the attributed function
25-
should be placed in the caller, rather than generating code to call the
26-
function where it is defined.
11+
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.
12+
13+
> [!EXAMPLE]
14+
> ```rust
15+
> #[inline]
16+
> pub fn example1() {}
17+
>
18+
> #[inline(always)]
19+
> pub fn example2() {}
20+
>
21+
> #[inline(never)]
22+
> pub fn example3() {}
23+
> ```
24+
25+
> [!NOTE]
26+
> `rustc` automatically inlines functions when doing so seems worthwhile. Use this attribute carefully as poor decisions about what to inline can slow down programs.
27+
28+
r[attributes.codegen.inline.syntax]
29+
The syntax for the `inline` attribute is:
30+
31+
```grammar,attributes
32+
@root InlineAttribute ->
33+
`inline` `(` `always` `)`
34+
| `inline` `(` `never` `)`
35+
| `inline`
36+
```
37+
38+
r[attributes.codegen.inline.allowed-positions]
39+
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] .
2740

2841
> [!NOTE]
29-
> 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.
42+
> `rustc` ignores use in other positions but lints against it. This may become an error in the future.
43+
44+
> [!NOTE]
45+
> 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.
46+
>
47+
> ```rust
48+
> // We allow attributes on statements.
49+
> #[inline] || (); // OK
50+
> #[inline] async {}; // OK
51+
> ```
52+
>
53+
> ```rust,compile_fail,E0658
54+
> // We don't yet allow attributes on expressions.
55+
> let f = #[inline] || (); // ERROR
56+
> ```
57+
58+
r[attributes.codegen.inline.duplicates]
59+
Only the first use of `inline` on a function has effect.
60+
61+
> [!NOTE]
62+
> `rustc` lints against any use following the first. This may become an error in the future.
3063
3164
r[attributes.codegen.inline.modes]
32-
There are three ways to use the inline attribute:
65+
The `inline` attribute supports these modes:
3366
34-
* `#[inline]` *suggests* performing an inline expansion.
35-
* `#[inline(always)]` *suggests* that an inline expansion should always be
36-
performed.
37-
* `#[inline(never)]` *suggests* that an inline expansion should never be
38-
performed.
67+
- `#[inline]` *suggests* performing inline expansion.
68+
- `#[inline(always)]` *suggests* that inline expansion should always be performed.
69+
- `#[inline(never)]` *suggests* that inline expansion should never be performed.
3970
4071
> [!NOTE]
41-
> `#[inline]` in every form is a hint, with no *requirements* on the language to place a copy of the attributed function in the caller.
72+
> In every form the attribute is a hint. The compiler may ignore it.
73+
74+
r[attributes.codegen.inline.trait]
75+
When `inline` is applied to a function in a [trait], it applies only to the code of the [default definition].
4276
77+
r[attributes.codegen.inline.async]
78+
When `inline` is applied to an [async function] or [async closure], it applies only to the code of the generated `poll` function.
79+
80+
> [!NOTE]
81+
> For more details, see [Rust issue #129347](https://github.com/rust-lang/rust/issues/129347).
82+
83+
r[attributes.codegen.inline.externally-exported]
84+
The `inline` attribute is ignored if the function is externally exported with [`no_mangle`] or [`export_name`].
85+
86+
<!-- template:attributes -->
4387
r[attributes.codegen.cold]
4488
### The `cold` attribute
4589
46-
The *`cold` [attribute]* suggests that the attributed function is unlikely to
47-
be called.
90+
r[attributes.codegen.cold.intro]
91+
The *`cold` [attribute]* suggests that the attributed function is unlikely to be called which may help the compiler produce better code.
92+
93+
> [!EXAMPLE]
94+
> ```rust
95+
> #[cold]
96+
> pub fn example() {}
97+
> ```
98+
99+
r[attributes.codegen.cold.syntax]
100+
The `cold` attribute uses the [MetaWord] syntax.
101+
102+
r[attributes.codegen.cold.allowed-positions]
103+
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] .
104+
105+
> [!NOTE]
106+
> `rustc` ignores use in other positions but lints against it. This may become an error in the future.
107+
108+
> [!NOTE]
109+
> 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.
110+
111+
<!-- 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). -->
112+
113+
r[attributes.codegen.cold.duplicates]
114+
Only the first use of `cold` on a function has effect.
115+
116+
> [!NOTE]
117+
> `rustc` lints against any use following the first. This may become an error in the future.
118+
119+
r[attributes.codegen.cold.trait]
120+
When `cold` is applied to a function in a [trait], it applies only to the code of the [default definition].
48121
49122
r[attributes.codegen.naked]
50123
## The `naked` attribute
@@ -655,11 +728,14 @@ r[attributes.codegen.instruction_set.syntax]
655728
The `instruction_set` attribute uses the [MetaListPaths] syntax to specify a single path consisting of the architecture family name and instruction set name.
656729
657730
r[attributes.codegen.instruction_set.allowed-positions]
658-
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].
731+
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] .
659732
660733
> [!NOTE]
661734
> `rustc` ignores use in other positions but lints against it. This may become an error in the future.
662735
736+
> [!NOTE]
737+
> 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.
738+
663739
r[attributes.codegen.instruction_set.duplicates]
664740
The `instruction_set` attribute may be used only once on a function.
665741
@@ -684,18 +760,31 @@ If the address of the function is taken as a function pointer, the low bit of th
684760
685761
[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu
686762
[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature
763+
[`export_name`]: abi.export_name
687764
[`is_aarch64_feature_detected`]: ../../std/arch/macro.is_aarch64_feature_detected.html
688765
[`is_x86_feature_detected`]: ../../std/arch/macro.is_x86_feature_detected.html
689766
[`Location`]: core::panic::Location
690767
[`naked_asm!`]: ../inline-assembly.md
768+
[`no_mangle`]: abi.no_mangle
691769
[`target_feature` conditional compilation option]: ../conditional-compilation.md#target_feature
692770
[`unused_variables`]: ../../rustc/lints/listing/warn-by-default.html#unused-variables
771+
[associated functions]: items.associated.fn
772+
[async blocks]: expr.block.async
773+
[async closure]: expr.closure.async
774+
[async function]: items.fn.async
693775
[attribute]: ../attributes.md
694776
[attributes]: ../attributes.md
777+
[bodies]: items.fn.body
778+
[closures]: expr.closure
779+
[default definition]: items.traits.associated-item-decls
780+
[free functions]: items.fn
695781
[function body]: ../items/functions.md#function-body
696782
[functions]: ../items/functions.md
783+
[inherent impl]: items.impl.inherent
697784
[rust-abi]: ../items/external-blocks.md#abi
698785
[target architecture]: ../conditional-compilation.md#target_arch
699-
[trait]: ../items/traits.md
786+
[trait]: items.traits
787+
[trait definition]: items.traits
788+
[trait impl]: items.impl.trait
700789
[undefined behavior]: ../behavior-considered-undefined.md
701790
[unsafe attribute]: ../attributes.md#r-attributes.safety

src/items/functions.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,21 @@ fn documented() {
417417
> Except for lints, it is idiomatic to only use outer attributes on function items.
418418
419419
r[items.fn.attributes.builtin-attributes]
420-
The attributes that have meaning on a function are [`cfg`], [`cfg_attr`], [`deprecated`],
421-
[`doc`], [`export_name`], [`link_section`], [`no_mangle`], [the lint check
422-
attributes], [`must_use`], [the procedural macro attributes], [the testing
423-
attributes], and [the optimization hint attributes]. Functions also accept
424-
attributes macros.
420+
The attributes that have meaning on a function are:
421+
422+
- [`cfg_attr`]
423+
- [`cfg`]
424+
- [`cold`]
425+
- [`deprecated`]
426+
- [`doc`]
427+
- [`export_name`]
428+
- [`inline`]
429+
- [`link_section`]
430+
- [`must_use`]
431+
- [`no_mangle`]
432+
- [Lint check attributes]
433+
- [Procedural macro attributes]
434+
- [Testing attributes]
425435

426436
r[items.fn.param-attributes]
427437
## Attributes on function parameters
@@ -471,10 +481,11 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
471481
[attributes]: ../attributes.md
472482
[`cfg`]: ../conditional-compilation.md#the-cfg-attribute
473483
[`cfg_attr`]: ../conditional-compilation.md#the-cfg_attr-attribute
474-
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
475-
[the procedural macro attributes]: ../procedural-macros.md
476-
[the testing attributes]: ../attributes/testing.md
477-
[the optimization hint attributes]: ../attributes/codegen.md#optimization-hints
484+
[lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
485+
[procedural macro attributes]: ../procedural-macros.md#attribute-macros
486+
[testing attributes]: ../attributes/testing.md
487+
[`cold`]: ../attributes/codegen.md#the-cold-attribute
488+
[`inline`]: ../attributes/codegen.md#the-inline-attribute
478489
[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute
479490
[`doc`]: ../../rustdoc/the-doc-attribute.html
480491
[`must_use`]: ../attributes/diagnostics.md#the-must_use-attribute

0 commit comments

Comments
 (0)