`]: ../special-types-and-traits.md#boxt
[`Pin`]: ../special-types-and-traits.md#pinp
[`Rc`]: ../special-types-and-traits.md#rct
+[_OuterAttribute_]: ../attributes.md
[traits]: traits.md
[type aliases]: type-aliases.md
[inherent implementations]: implementations.md#inherent-implementations
@@ -349,3 +360,4 @@ fn main() {
[function item]: ../types/function-item.md
[method call operator]: ../expressions/method-call-expr.md
[path]: ../paths.md
+[regular function parameters]: functions.md#attributes-on-function-parameters
\ No newline at end of file
diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md
index f3e692ac9..8777ef532 100644
--- a/src/items/external-blocks.md
+++ b/src/items/external-blocks.md
@@ -24,14 +24,14 @@
> _NamedFunctionParam_ ( `,` _NamedFunctionParam_ )\* `,`?
>
> _NamedFunctionParam_ :\
-> ( [IDENTIFIER] | `_` ) `:` [_Type_]
+> [_OuterAttribute_]\* ( [IDENTIFIER] | `_` ) `:` [_Type_]
>
> _NamedFunctionParametersWithVariadics_ :\
-> ( _NamedFunctionParam_ `,` )\* _NamedFunctionParam_ `,` `...`
+> ( _NamedFunctionParam_ `,` )\* _NamedFunctionParam_ `,` [_OuterAttribute_]\* `...`
External blocks provide _declarations_ of items that are not _defined_ in the
current crate and are the basis of Rust's foreign function interface. These are
-akin to unchecked imports.
+akin to unchecked imports.
Two kind of item _declarations_ are allowed in external blocks: [functions] and
[statics]. Calling functions or accessing statics that are declared in external
@@ -162,6 +162,11 @@ extern {
}
```
+### Attributes on function parameters
+
+Attributes on extern function parameters follow the same rules and
+restrictions as [regular function parameters].
+
[IDENTIFIER]: ../identifiers.md
[WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html
[functions]: functions.md
@@ -177,3 +182,4 @@ extern {
[_Visibility_]: ../visibility-and-privacy.md
[_WhereClause_]: generics.md#where-clauses
[attributes]: ../attributes.md
+[regular function parameters]: functions.md#attributes-on-function-parameters
\ No newline at end of file
diff --git a/src/items/functions.md b/src/items/functions.md
index 7c93dc423..e5f3d5bee 100644
--- a/src/items/functions.md
+++ b/src/items/functions.md
@@ -17,7 +17,7 @@
> _FunctionParam_ (`,` _FunctionParam_)\* `,`?
>
> _FunctionParam_ :\
-> [_Pattern_] `:` [_Type_]
+> [_OuterAttribute_]\* [_Pattern_] `:` [_Type_]
>
> _FunctionReturnType_ :\
> `->` [_Type_]
@@ -244,12 +244,40 @@ fn test_only() {
> Note: Except for lints, it is idiomatic to only use outer attributes on
> function items.
-The attributes that have meaning on a function are [`cfg`], [`deprecated`],
+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.
+## Attributes on function parameters
+
+[Outer attributes][attributes] are allowed on function parameters and the
+permitted [built-in attributes] are restricted to `cfg`, `cfg_attr`, `allow`,
+`warn`, `deny`, and `forbid`.
+
+```rust
+fn len(
+ #[cfg(windows)] slice: &[u16],
+ #[cfg(not(windows))] slice: &[u8],
+) -> usize {
+ slice.len()
+}
+```
+
+Inert helper attributes used by procedural macro attributes applied to items are also
+allowed but be careful to not include these inert attributes in your final `TokenStream`.
+
+For example, the following code defines an inert `some_inert_attribute` attribute that
+is not formally defined anywhere and the `some_proc_macro_attribute` procedural macro is
+responsible for detecting its presence and removing it from the output token stream.
+
+```rust,ignore
+#[some_proc_macro_attribute]
+fn foo_oof(#[some_inert_attribute] arg: u8) {
+}
+```
+
[IDENTIFIER]: ../identifiers.md
[RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals
[STRING_LITERAL]: ../tokens.md#string-literals
@@ -258,6 +286,7 @@ attributes macros.
[_Pattern_]: ../patterns.md
[_Type_]: ../types.md#type-expressions
[_WhereClause_]: generics.md#where-clauses
+[_OuterAttribute_]: ../attributes.md
[const context]: ../const_eval.md#const-context
[external blocks]: external-blocks.md
[path]: ../paths.md
@@ -267,7 +296,8 @@ attributes macros.
[*function item type*]: ../types/function-item.md
[Trait]: traits.md
[attributes]: ../attributes.md
-[`cfg`]: ../conditional-compilation.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
@@ -282,3 +312,4 @@ attributes macros.
[`link_section`]: ../abi.md#the-link_section-attribute
[`no_mangle`]: ../abi.md#the-no_mangle-attribute
[external_block_abi]: external-blocks.md#abi
+[built-in attributes]: ../attributes.html#built-in-attributes-index
diff --git a/src/items/traits.md b/src/items/traits.md
index e835a6097..dea8ecad0 100644
--- a/src/items/traits.md
+++ b/src/items/traits.md
@@ -38,7 +38,7 @@
> _TraitFunctionParam_ (`,` _TraitFunctionParam_)\* `,`?
>
> _TraitFunctionParam_[†](#parameter-patterns) :\
-> ( [_Pattern_] `:` )? [_Type_]
+> [_OuterAttribute_]\* ( [_Pattern_] `:` )? [_Type_]
>
> _TraitConst_ :\
> `const` [IDENTIFIER] `:` [_Type_] ( `=` [_Expression_] )? `;`
diff --git a/src/types/function-pointer.md b/src/types/function-pointer.md
index 88ef50c24..912ee932a 100644
--- a/src/types/function-pointer.md
+++ b/src/types/function-pointer.md
@@ -15,10 +15,10 @@
> _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )\* `,`?
>
> _MaybeNamedParam_ :\
-> ( ( [IDENTIFIER] | `_` ) `:` )? [_Type_]
+> [_OuterAttribute_]\* ( ( [IDENTIFIER] | `_` ) `:` )? [_Type_]
>
> _MaybeNamedFunctionParametersVariadic_ :\
-> ( _MaybeNamedParam_ `,` )\* _MaybeNamedParam_ `,` `...`
+> ( _MaybeNamedParam_ `,` )\* _MaybeNamedParam_ `,` [_OuterAttribute_]\* `...`
Function pointer types, written using the `fn` keyword, refer to a function
whose identity is not necessarily known at compile-time. They can be created
@@ -44,13 +44,20 @@ let bo: Binop = add;
x = bo(5,7);
```
+## Attributes on function pointer parameters
+
+Attributes on function pointer parameters follow the same rules and
+restrictions as [regular function parameters].
+
[IDENTIFIER]: ../identifiers.md
[_ForLifetimes_]: ../items/generics.md#where-clauses
[_FunctionQualifiers_]: ../items/functions.md
[_TypeNoBounds_]: ../types.md#type-expressions
[_Type_]: ../types.md#type-expressions
+[_OuterAttribute_]: ../attributes.md
[`extern`]: ../items/external-blocks.md
[closures]: closure.md
[extern function]: ../items/functions.md#extern-function-qualifier
[function items]: function-item.md
[unsafe function]: ../unsafe-functions.md
+[regular function parameters]: ../items/functions.md#attributes-on-function-parameters
\ No newline at end of file