Skip to content

Commit 0757a2d

Browse files
authored
Merge pull request #657 from c410-f3r/attrs-fn
Add reference for attributes in function parameters
2 parents 1902ae4 + 1f1fcfb commit 0757a2d

File tree

7 files changed

+80
-11
lines changed

7 files changed

+80
-11
lines changed

src/attributes.md

+6
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ Attributes may be applied to many things in the language:
5050
* [Generic lifetime or type parameter][generics] accept outer attributes.
5151
* Expressions accept outer attributes in limited situations, see [Expression
5252
Attributes] for details.
53+
* [Function][functions], [closure]] and [function pointer]
54+
parameters accept outer attributes. This includes attributes on variadic parameters
55+
denoted with `...` in function pointers and [external blocks][variadic functions].
5356

5457
Some examples of attributes:
5558

@@ -304,3 +307,6 @@ The following is an index of all built-in attributes.
304307
[statements]: statements.md
305308
[struct]: items/structs.md
306309
[union]: items/unions.md
310+
[closure]: expressions/closure-expr.md
311+
[function pointer]: types/function-pointer.md
312+
[variadic functions]: items/external-blocks.html#variadic-functions

src/expressions/closure-expr.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
> &nbsp;&nbsp; _ClosureParam_ (`,` _ClosureParam_)<sup>\*</sup> `,`<sup>?</sup>
1111
>
1212
> _ClosureParam_ :\
13-
> &nbsp;&nbsp; [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
13+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
1414
1515
A _closure expression_ defines a closure and denotes it as a value, in a single
1616
expression. A closure expression is a pipe-symbol-delimited (`|`) list of
@@ -67,13 +67,20 @@ let word = "konnichiwa".to_owned();
6767
ten_times(move |j| println!("{}, {}", word, j));
6868
```
6969

70+
## Attributes on closure parameters
71+
72+
Attributes on closure parameters follow the same rules and restrictions as
73+
[regular function parameters].
74+
7075
[block]: block-expr.md
7176
[function definitions]: ../items/functions.md
7277
[patterns]: ../patterns.md
78+
[regular function parameters]: ../items/functions.md#attributes-on-function-parameters
7379

7480
[_Expression_]: ../expressions.md
7581
[_BlockExpression_]: block-expr.md
7682
[_TypeNoBounds_]: ../types.md#type-expressions
7783
[_Pattern_]: ../patterns.md
7884
[_Type_]: ../types.md#type-expressions
7985
[`let` binding]: ../statements.md#let-statements
86+
[_OuterAttribute_]: ../attributes.md

src/items/associated-items.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,13 @@ let _: f64 = f64::from_i32(42);
8686
> &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]
8787
>
8888
> _SelfParam_ :\
89-
> &nbsp;&nbsp; &nbsp;&nbsp; (`&` | `&` [_Lifetime_])<sup>?</sup> `mut`<sup>?</sup> `self`\
90-
> &nbsp;&nbsp; | `mut`<sup>?</sup> `self` (`:` [_Type_])<sup>?</sup>
89+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( _ShorthandSelf_ | _TypedSelf_ )
90+
>
91+
> _ShorthandSelf_ :\
92+
> &nbsp;&nbsp; (`&` | `&` [_Lifetime_])<sup>?</sup> `mut`<sup>?</sup> `self`
93+
>
94+
> _TypedSelf_ :\
95+
> &nbsp;&nbsp; `mut`<sup>?</sup> `self` `:` [_Type_]
9196
9297
Associated functions whose first parameter is named `self` are called *methods*
9398
and may be invoked using the [method call operator], for example, `x.foo()`, as
@@ -190,6 +195,11 @@ let bounding_box = circle_shape.bounding_box();
190195
> methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and
191196
> an error as of the 2018 edition. All parameters must have an argument name.
192197
198+
#### Attributes on method parameters
199+
200+
Attributes on method parameters follow the same rules and restrictions as
201+
[regular function parameters].
202+
193203
## Associated Types
194204

195205
*Associated types* are [type aliases] associated with another type. Associated
@@ -336,6 +346,7 @@ fn main() {
336346
[`Box<Self>`]: ../special-types-and-traits.md#boxt
337347
[`Pin<P>`]: ../special-types-and-traits.md#pinp
338348
[`Rc<Self>`]: ../special-types-and-traits.md#rct
349+
[_OuterAttribute_]: ../attributes.md
339350
[traits]: traits.md
340351
[type aliases]: type-aliases.md
341352
[inherent implementations]: implementations.md#inherent-implementations
@@ -349,3 +360,4 @@ fn main() {
349360
[function item]: ../types/function-item.md
350361
[method call operator]: ../expressions/method-call-expr.md
351362
[path]: ../paths.md
363+
[regular function parameters]: functions.md#attributes-on-function-parameters

src/items/external-blocks.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
> &nbsp;&nbsp; _NamedFunctionParam_ ( `,` _NamedFunctionParam_ )<sup>\*</sup> `,`<sup>?</sup>
2626
>
2727
> _NamedFunctionParam_ :\
28-
> &nbsp;&nbsp; ( [IDENTIFIER] | `_` ) `:` [_Type_]
28+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( [IDENTIFIER] | `_` ) `:` [_Type_]
2929
>
3030
> _NamedFunctionParametersWithVariadics_ :\
31-
> &nbsp;&nbsp; ( _NamedFunctionParam_ `,` )<sup>\*</sup> _NamedFunctionParam_ `,` `...`
31+
> &nbsp;&nbsp; ( _NamedFunctionParam_ `,` )<sup>\*</sup> _NamedFunctionParam_ `,` [_OuterAttribute_]<sup>\*</sup> `...`
3232
3333
External blocks provide _declarations_ of items that are not _defined_ in the
3434
current crate and are the basis of Rust's foreign function interface. These are
@@ -163,6 +163,11 @@ extern {
163163
}
164164
```
165165

166+
### Attributes on function parameters
167+
168+
Attributes on extern function parameters follow the same rules and
169+
restrictions as [regular function parameters].
170+
166171
[IDENTIFIER]: ../identifiers.md
167172
[WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html
168173
[functions]: functions.md
@@ -179,3 +184,4 @@ extern {
179184
[_Visibility_]: ../visibility-and-privacy.md
180185
[_WhereClause_]: generics.md#where-clauses
181186
[attributes]: ../attributes.md
187+
[regular function parameters]: functions.md#attributes-on-function-parameters

src/items/functions.md

+34-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
> &nbsp;&nbsp; _FunctionParam_ (`,` _FunctionParam_)<sup>\*</sup> `,`<sup>?</sup>
2121
>
2222
> _FunctionParam_ :\
23-
> &nbsp;&nbsp; [_Pattern_] `:` [_Type_]
23+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_] `:` [_Type_]
2424
>
2525
> _FunctionReturnType_ :\
2626
> &nbsp;&nbsp; `->` [_Type_]
@@ -345,12 +345,40 @@ fn test_only() {
345345
> Note: Except for lints, it is idiomatic to only use outer attributes on
346346
> function items.
347347
348-
The attributes that have meaning on a function are [`cfg`], [`deprecated`],
348+
The attributes that have meaning on a function are [`cfg`], [`cfg_attr`], [`deprecated`],
349349
[`doc`], [`export_name`], [`link_section`], [`no_mangle`], [the lint check
350350
attributes], [`must_use`], [the procedural macro attributes], [the testing
351351
attributes], and [the optimization hint attributes]. Functions also accept
352352
attributes macros.
353353

354+
## Attributes on function parameters
355+
356+
[Outer attributes][attributes] are allowed on function parameters and the
357+
permitted [built-in attributes] are restricted to `cfg`, `cfg_attr`, `allow`,
358+
`warn`, `deny`, and `forbid`.
359+
360+
```rust
361+
fn len(
362+
#[cfg(windows)] slice: &[u16],
363+
#[cfg(not(windows))] slice: &[u8],
364+
) -> usize {
365+
slice.len()
366+
}
367+
```
368+
369+
Inert helper attributes used by procedural macro attributes applied to items are also
370+
allowed but be careful to not include these inert attributes in your final `TokenStream`.
371+
372+
For example, the following code defines an inert `some_inert_attribute` attribute that
373+
is not formally defined anywhere and the `some_proc_macro_attribute` procedural macro is
374+
responsible for detecting its presence and removing it from the output token stream.
375+
376+
```rust,ignore
377+
#[some_proc_macro_attribute]
378+
fn foo_oof(#[some_inert_attribute] arg: u8) {
379+
}
380+
```
381+
354382
[IDENTIFIER]: ../identifiers.md
355383
[RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals
356384
[STRING_LITERAL]: ../tokens.md#string-literals
@@ -359,6 +387,7 @@ attributes macros.
359387
[_Pattern_]: ../patterns.md
360388
[_Type_]: ../types.md#type-expressions
361389
[_WhereClause_]: generics.md#where-clauses
390+
[_OuterAttribute_]: ../attributes.md
362391
[const context]: ../const_eval.md#const-context
363392
[external block]: external-blocks.md
364393
[path]: ../paths.md
@@ -368,7 +397,8 @@ attributes macros.
368397
[*function item type*]: ../types/function-item.md
369398
[Trait]: traits.md
370399
[attributes]: ../attributes.md
371-
[`cfg`]: ../conditional-compilation.md
400+
[`cfg`]: ../conditional-compilation.md#the-cfg-attribute
401+
[`cfg_attr`]: ../conditional-compilation.md#the-cfg_attr-attribute
372402
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
373403
[the procedural macro attributes]: ../procedural-macros.md
374404
[the testing attributes]: ../attributes/testing.md
@@ -383,3 +413,4 @@ attributes macros.
383413
[`link_section`]: ../abi.md#the-link_section-attribute
384414
[`no_mangle`]: ../abi.md#the-no_mangle-attribute
385415
[external_block_abi]: external-blocks.md#abi
416+
[built-in attributes]: ../attributes.html#built-in-attributes-index

src/items/traits.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
> &nbsp;&nbsp; _TraitFunctionParam_ (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup>
3939
>
4040
> _TraitFunctionParam_<sup>[](#parameter-patterns)</sup> :\
41-
> &nbsp;&nbsp; ( [_Pattern_] `:` )<sup>?</sup> [_Type_]
41+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( [_Pattern_] `:` )<sup>?</sup> [_Type_]
4242
>
4343
> _TraitConst_ :\
4444
> &nbsp;&nbsp; `const` [IDENTIFIER] `:` [_Type_]&nbsp;( `=` [_Expression_] )<sup>?</sup> `;`

src/types/function-pointer.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
> &nbsp;&nbsp; _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )<sup>\*</sup> `,`<sup>?</sup>
1616
>
1717
> _MaybeNamedParam_ :\
18-
> &nbsp;&nbsp; ( ( [IDENTIFIER] | `_` ) `:` )<sup>?</sup> [_Type_]
18+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( ( [IDENTIFIER] | `_` ) `:` )<sup>?</sup> [_Type_]
1919
>
2020
> _MaybeNamedFunctionParametersVariadic_ :\
21-
> &nbsp;&nbsp; ( _MaybeNamedParam_ `,` )<sup>\*</sup> _MaybeNamedParam_ `,` `...`
21+
> &nbsp;&nbsp; ( _MaybeNamedParam_ `,` )<sup>\*</sup> _MaybeNamedParam_ `,` [_OuterAttribute_]<sup>\*</sup> `...`
2222
2323
Function pointer types, written using the `fn` keyword, refer to a function
2424
whose identity is not necessarily known at compile-time. They can be created
@@ -44,13 +44,20 @@ let bo: Binop = add;
4444
x = bo(5,7);
4545
```
4646

47+
## Attributes on function pointer parameters
48+
49+
Attributes on function pointer parameters follow the same rules and
50+
restrictions as [regular function parameters].
51+
4752
[IDENTIFIER]: ../identifiers.md
4853
[_ForLifetimes_]: ../items/generics.md#where-clauses
4954
[_FunctionQualifiers_]: ../items/functions.md
5055
[_TypeNoBounds_]: ../types.md#type-expressions
5156
[_Type_]: ../types.md#type-expressions
57+
[_OuterAttribute_]: ../attributes.md
5258
[`extern`]: ../items/external-blocks.md
5359
[closures]: closure.md
5460
[extern function]: ../items/functions.md#extern-function-qualifier
5561
[function items]: function-item.md
5662
[unsafe function]: ../unsafe-functions.md
63+
[regular function parameters]: ../items/functions.md#attributes-on-function-parameters

0 commit comments

Comments
 (0)