diff --git a/src/attributes.md b/src/attributes.md index df2bb460f..eb82392e4 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -50,6 +50,9 @@ Attributes may be applied to many things in the language: * [Generic lifetime or type parameter][generics] accept outer attributes. * Expressions accept outer attributes in limited situations, see [Expression Attributes] for details. +* [Function][function], [closure][closure] and [function pointer][function pointer] + parameters accept outer attributes. This includes attributes on variadic parameters + denoted with `...` in function pointers and [external blocks][variadic functions]. Some examples of attributes: @@ -306,3 +309,6 @@ The following is an index of all built-in attributes. [statements]: statements.md [struct]: items/structs.md [union]: items/unions.md +[closure]: expressions/closure-expr.md +[function pointer]: types/function-pointer.md +[variadic functions]: items/external-blocks.html#variadic-functions \ No newline at end of file diff --git a/src/expressions/closure-expr.md b/src/expressions/closure-expr.md index aa9299bd6..74b8e203c 100644 --- a/src/expressions/closure-expr.md +++ b/src/expressions/closure-expr.md @@ -10,7 +10,7 @@ >    _ClosureParam_ (`,` _ClosureParam_)\* `,`? > > _ClosureParam_ :\ ->    [_Pattern_] ( `:` [_Type_] )? +>    [_OuterAttribute_]\* [_Pattern_] ( `:` [_Type_] )? A _closure expression_ defines a closure and denotes it as a value, in a single expression. A closure expression is a pipe-symbol-delimited (`|`) list of @@ -67,9 +67,15 @@ let word = "konnichiwa".to_owned(); ten_times(move |j| println!("{}, {}", word, j)); ``` +## Attributes on closure parameters + +Attributes on closure parameters follow the same rules and restrictions as +[regular function parameters]. + [block]: block-expr.md [function definitions]: ../items/functions.md [patterns]: ../patterns.md +[regular function parameters]: ../items/functions.md#attributes-on-function-parameters [_Expression_]: ../expressions.md [_BlockExpression_]: block-expr.md @@ -77,3 +83,4 @@ ten_times(move |j| println!("{}, {}", word, j)); [_Pattern_]: ../patterns.md [_Type_]: ../types.md#type-expressions [`let` binding]: ../statements.md#let-statements +[_OuterAttribute_]: ../attributes.md \ No newline at end of file diff --git a/src/items/associated-items.md b/src/items/associated-items.md index e8a18ad58..b8d5addca 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -86,8 +86,13 @@ let _: f64 = f64::from_i32(42); >       [_BlockExpression_] > > _SelfParam_ :\ ->       (`&` | `&` [_Lifetime_])? `mut`? `self`\ ->    | `mut`? `self` (`:` [_Type_])? +>    [_OuterAttribute_]\* ( _ShorthandSelf_ | _TypedSelf_ ) +> +> _ShorthandSelf_ :\ +>    (`&` | `&` [_Lifetime_])? `mut`? `self` +> +> _TypedSelf_ :\ +>    `mut`? `self` `:` [_Type_] Associated functions whose first parameter is named `self` are called *methods* 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(); > methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and > an error as of the 2018 edition. All parameters must have an argument name. +#### Attributes on method parameters + +Attributes on method parameters follow the same rules and restrictions as +[regular function parameters]. + ## Associated Types *Associated types* are [type aliases] associated with another type. Associated @@ -336,6 +346,7 @@ fn main() { [`Box`]: ../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..57ec920fb 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,27 @@ 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`. For example: + +```rust +fn len( + #[cfg(windows)] slice: &[u16], + #[cfg(not(windows))] slice: &[u8], +) -> usize { + slice.len() +} +``` + [IDENTIFIER]: ../identifiers.md [RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals [STRING_LITERAL]: ../tokens.md#string-literals @@ -258,6 +273,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 +283,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 +299,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