Skip to content

Commit ce592df

Browse files
authored
Merge pull request #528 from ehuss/attribute-update
Update attribute documentation.
2 parents 456f735 + 609d740 commit ce592df

5 files changed

+116
-69
lines changed

src/attributes.md

+78-43
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,39 @@
11
# Attributes
22

33
> **<sup>Syntax</sup>**\
4-
> _Attribute_ :\
5-
> &nbsp;&nbsp; _InnerAttribute_ | _OuterAttribute_
6-
>
74
> _InnerAttribute_ :\
8-
> &nbsp;&nbsp; `#![` MetaItem `]`
5+
> &nbsp;&nbsp; `#` `!` `[` _Attr_ `]`
96
>
107
> _OuterAttribute_ :\
11-
> &nbsp;&nbsp; `#[` MetaItem `]`
12-
>
13-
> _MetaItem_ :\
14-
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_]\
15-
> &nbsp;&nbsp; | [_SimplePath_] `=` [_LiteralExpression_]<sub>_without suffix_</sub>\
16-
> &nbsp;&nbsp; | [_SimplePath_] `(` _MetaSeq_<sup>?</sup> `)`
8+
> &nbsp;&nbsp; `#` `[` _Attr_ `]`
179
>
18-
> _MetaSeq_ :\
19-
> &nbsp;&nbsp; _MetaItemInner_ ( `,` MetaItemInner )<sup>\*</sup> `,`<sup>?</sup>
10+
> _Attr_ :\
11+
> &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>
2012
>
21-
> _MetaItemInner_ :\
22-
> &nbsp;&nbsp; &nbsp;&nbsp; _MetaItem_\
23-
> &nbsp;&nbsp; | [_LiteralExpression_]<sub>_without suffix_</sub>
13+
> _AttrInput_ :\
14+
> &nbsp;&nbsp; &nbsp;&nbsp; [_DelimTokenTree_]\
15+
> &nbsp;&nbsp; | `=` [_LiteralExpression_]<sub>_without suffix_</sub>
2416
2517
An _attribute_ is a general, free-form metadatum that is interpreted according
2618
to name, convention, and language and compiler version. Attributes are modeled
2719
on Attributes in [ECMA-335], with the syntax coming from [ECMA-334] \(C#).
2820

29-
Attributes may appear as any of:
21+
_Inner attributes_, written with a bang (`!`) after the hash (`#`), apply to the
22+
item that the attribute is declared within. _Outer attributes_, written without
23+
the bang after the hash, apply to the thing that follows the attribute.
3024

31-
* A single identifier, the _attribute name_
32-
* An identifier followed by the equals sign '=' and a literal, providing a
33-
key/value pair
34-
* An identifier followed by a parenthesized list of sub-attribute arguments
35-
which include literals
25+
The attribute consists of a path to the attribute, followed by an optional
26+
delimited token tree whose interpretation is defined by the attribute.
27+
Attributes other than macro attributes also allow the input to be an equals
28+
sign (`=`) followed by a literal expression. See the [meta item
29+
syntax](#meta-item-attribute-syntax) below for more details.
3630

37-
Literal values must not include integer or float type suffixes.
31+
Attributes can be classified into the following kinds:
3832

39-
_Inner attributes_, written with a bang ("!") after the hash ("#"), apply to the
40-
item that the attribute is declared within. _Outer attributes_, written without
41-
the bang after the hash, apply to the thing that follows the attribute.
33+
* Built-in attributes
34+
* [Macro attributes][attribute macro]
35+
* [Derive macro helper attributes]
36+
* [Tool attributes](#tool-attributes)
4237

4338
Attributes may be applied to many things in the language:
4439

@@ -87,11 +82,34 @@ fn some_unused_variables() {
8782
}
8883
```
8984

90-
There are three kinds of attributes:
85+
## Meta Item Attribute Syntax
9186

92-
* Built-in attributes
93-
* Macro attributes
94-
* Derive macro helper attributes
87+
A "meta item" is the syntax used for the _Attr_ rule by most built-in
88+
attributes and the [`meta` macro fragment specifier]. It has the following
89+
grammar:
90+
91+
> **<sup>Syntax</sup>**\
92+
> _MetaItem_ :\
93+
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_]\
94+
> &nbsp;&nbsp; | [_SimplePath_] `=` [_LiteralExpression_]<sub>_without suffix_</sub>\
95+
> &nbsp;&nbsp; | [_SimplePath_] `(` _MetaSeq_<sup>?</sup> `)`
96+
>
97+
> _MetaSeq_ :\
98+
> &nbsp;&nbsp; _MetaItemInner_ ( `,` MetaItemInner )<sup>\*</sup> `,`<sup>?</sup>
99+
>
100+
> _MetaItemInner_ :\
101+
> &nbsp;&nbsp; &nbsp;&nbsp; _MetaItem_\
102+
> &nbsp;&nbsp; | [_LiteralExpression_]<sub>_without suffix_</sub>
103+
104+
Literal expressions in meta items must not include integer or float type
105+
suffixes.
106+
107+
Some examples of meta items are:
108+
- `no_std`
109+
- `doc = "example"`
110+
- `cfg(any())`
111+
- `deprecated(since = "1.2.0", note = "text")`
112+
- `repr(align(32))`
95113

96114
## Active and inert attributes
97115

@@ -139,28 +157,18 @@ names have meaning.
139157

140158
On an `extern` block, the following attributes are interpreted:
141159

142-
- `link_args` - specify arguments to the linker, rather than just the library
143-
name and type. This is feature gated and the exact behavior is
144-
implementation-defined (due to variety of linker invocation syntax).
145160
- `link` - indicate that a native library should be linked to for the
146161
declarations in this block to be linked correctly. `link` supports an optional
147162
`kind` key with three possible values: `dylib`, `static`, and `framework`. See
148163
[external blocks](items/external-blocks.html) for more about external blocks.
149164
Two examples: `#[link(name = "readline")]` and
150165
`#[link(name = "CoreFoundation", kind = "framework")]`.
151-
- `linked_from` - indicates what native library this block of FFI items is
152-
coming from. This attribute is of the form `#[linked_from = "foo"]` where
153-
`foo` is the name of a library in either `#[link]` or a `-l` flag. This
154-
attribute is currently required to export symbols from a Rust dynamic library
155-
on Windows, and it is feature gated behind the `linked_from` feature.
156166

157167
On declarations inside an `extern` block, the following attributes are
158168
interpreted:
159169

160170
- `link_name` - the name of the symbol that this function or static should be
161171
imported as.
162-
- `linkage` - on a static, this specifies the [linkage
163-
type](http://llvm.org/docs/LangRef.html#linkage-types).
164172

165173
See [type layout](type-layout.html) for documentation on the `repr` attribute
166174
which can be used to control type layout.
@@ -175,8 +183,6 @@ which can be used to control type layout.
175183
macros named. The `extern crate` must appear at the crate root, not inside
176184
`mod`, which ensures proper function of the `$crate` macro variable.
177185

178-
- `macro_reexport` on an `extern crate` — re-export the named macros.
179-
180186
- `macro_export` - export a `macro_rules` macro for cross-crate usage.
181187

182188
- `no_link` on an `extern crate` — even if we load this crate for macros, don't
@@ -371,8 +377,7 @@ They only get checked when the associated tool is active, so if you try to use a
371377

372378
Otherwise, they work just like regular lint attributes:
373379

374-
375-
```rust,ignore
380+
```rust
376381
// set the entire `pedantic` clippy lint group to warn
377382
#![warn(clippy::pedantic)]
378383
// silence warnings from the `filter_map` clippy lint
@@ -552,6 +557,34 @@ impl<T: PartialEq> PartialEq for Foo<T> {
552557

553558
You can implement `derive` for your own traits through [procedural macros].
554559

560+
## Tool attributes
561+
562+
The compiler may allow attributes for external tools where each tool resides
563+
in its own namespace. The first segment of the attribute path is the name of
564+
the tool, with one or more additional segments whose interpretation is up to
565+
the tool.
566+
567+
When a tool is not in use, the tool's attributes are accepted without a
568+
warning. When the tool is in use, the tool is responsible for processing and
569+
interpretation of its attributes.
570+
571+
Tool attributes are not available if the [`no_implicit_prelude`] attribute is
572+
used.
573+
574+
```rust
575+
// Tells the rustfmt tool to not format the following element.
576+
#[rustfmt::skip]
577+
struct S {
578+
}
579+
580+
// Controls the "cyclomatic complexity" threshold for the clippy tool.
581+
#[clippy::cyclomatic_complexity = "100"]
582+
pub fn f() {}
583+
```
584+
585+
> Note: `rustc` currently recognizes the tools "clippy" and "rustfmt".
586+
587+
[_DelimTokenTree_]: macros.html
555588
[_LiteralExpression_]: expressions/literal-expr.html
556589
[_SimplePath_]: paths.html#simple-paths
557590
[`no_implicit_prelude`]: items/modules.html#prelude-items
@@ -585,6 +618,7 @@ You can implement `derive` for your own traits through [procedural macros].
585618
[external blocks]: items/external-blocks.html
586619
[items]: items.html
587620
[attribute macro]: procedural-macros.html#attribute-macros
621+
[derive macro helper attributes]: procedural-macros.html#derive-macro-helper-attributes
588622
[function-like macro]: procedural-macros.html#function-like-procedural-macros
589623
[conditional compilation]: conditional-compilation.html
590624
[derive macro]: procedural-macros.html#derive-macros
@@ -594,3 +628,4 @@ You can implement `derive` for your own traits through [procedural macros].
594628
[where clause]: items/where-clauses.html
595629
[trait or lifetime bounds]: trait-bounds.html
596630
[Expression Attributes]: expressions.html#expression-attributes
631+
[`meta` macro fragment specifier]: macros-by-example.html

src/conditional-compilation.md

+22-10
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Example values:
104104
* `"android"`
105105
* `"freebsd"`
106106
* `"dragonfly"`
107-
* `"bitrig"`
107+
* `"bitrig"`
108108
* `"openbsd"`
109109
* `"netbsd"`
110110

@@ -151,7 +151,7 @@ Key-value option set once with the target's pointer width in bits. For example,
151151
for targets with 32-bit pointers, this is set to `"32"`. Likewise, it is set
152152
to `"64"` for targets with 64-bit pointers.
153153

154-
<!-- Are there targets that have a different bit number? -->
154+
<!-- Are there targets that have a different bit number? -->
155155

156156
### `target_vendor`
157157

@@ -235,16 +235,16 @@ generic parameters.
235235

236236
> **<sup>Syntax</sup>**\
237237
> _CfgAttrAttribute_ :\
238-
> &nbsp;&nbsp; `cfg_attr` `(` _ConfigurationPredicate_ `,` [_MetaItem_] `,`<sup>?</sup> `)`
238+
> &nbsp;&nbsp; `cfg_attr` `(` _ConfigurationPredicate_ `,` _CfgAttrs_<sup>?</sup> `)`
239+
>
240+
> _CfgAttrs_ :\
241+
> &nbsp;&nbsp; [_Attr_]&nbsp;(`,` [_Attr_])<sup>\*</sup> `,`<sup>?</sup>
239242
240243
The `cfg_attr` [attribute] conditionally includes [attributes] based on a
241244
configuration predicate.
242245

243-
It is written as `cfg_attr` followed by `(`, a configuration predicate, a
244-
[metaitem], an optional `,`, and finally a `)`.
245-
246-
When the configuration predicate is true, this attribute expands out to be an
247-
attribute of the attribute metaitem. For example, the following module will
246+
When the configuration predicate is true, this attribute expands out to the
247+
attributes listed after the predicate. For example, the following module will
248248
either be found at `linux.rs` or `windows.rs` based on the target.
249249

250250
```rust,ignore
@@ -253,6 +253,19 @@ either be found at `linux.rs` or `windows.rs` based on the target.
253253
mod os;
254254
```
255255

256+
Zero, one, or more attributes may be listed. Multiple attributes will each be
257+
expanded into separate attributes. For example:
258+
259+
```rust,ignore
260+
#[cfg_attr(feature = "magic", sparkles, crackles)]
261+
fn bewitched() {}
262+
263+
// When the `magic` feature flag is enabled, the above will expand to:
264+
#[sparkles]
265+
#[crackles]
266+
fn bewitched() {}
267+
```
268+
256269
> **Note**: The `cfg_attr` can expand to another `cfg_attr`. For example,
257270
> `#[cfg_attr(linux, cfg_attr(feature = "multithreaded", some_other_attribute))`
258271
> is valid. This example would be equivalent to
@@ -284,7 +297,7 @@ println!("I'm running on a {} machine!", machine_kind);
284297
[IDENTIFIER]: identifiers.html
285298
[RAW_STRING_LITERAL]: tokens.html#raw-string-literals
286299
[STRING_LITERAL]: tokens.html#string-literals
287-
[_MetaItem_]: attributes.html
300+
[_Attr_]: attributes.html
288301
[`--cfg`]: ../rustc/command-line-arguments.html#a--cfg-configure-the-compilation-environment
289302
[`--test`]: ../rustc/command-line-arguments.html#a--test-build-a-test-harness
290303
[`cfg`]: #the-cfg-attribute
@@ -296,4 +309,3 @@ println!("I'm running on a {} machine!", machine_kind);
296309
[crate type]: linkage.html
297310
[expressions]: expressions.html
298311
[items]: items.html
299-
[metaitem]: attributes.html

src/macros-by-example.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ syntax named by _designator_. Valid designators are:
8080
[_Expression_]: expressions.html
8181
[_Item_]: items.html
8282
[_LiteralExpression_]: expressions/literal-expr.html
83-
[_MetaItem_]: attributes.html
83+
[_MetaItem_]: attributes.html#meta-item-attribute-syntax
8484
[_Pattern_]: patterns.html
8585
[_Statement_]: statements.html
8686
[_TokenTree_]: macros.html#macro-invocation

src/procedural-macros.md

+13-13
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ These macros are defined by a [public]&#32;[function] with the `proc_macro`
7777
[`TokenStream`] is what is inside the delimiters of the macro invocation and the
7878
output [`TokenStream`] replaces the entire macro invocation. It may contain an
7979
arbitrary number of [items]. These macros cannot expand to syntax that defines
80-
new `macro_rule` style macros.
80+
new `macro_rules` style macros.
8181
8282
For example, the following macro definition ignores its input and outputs a
8383
function `answer` into its scope.
@@ -195,14 +195,14 @@ struct Struct {
195195
*Attribute macros* define new [attributes] which can be attached to [items].
196196

197197
Attribute macros are defined by a [public]&#32;[function] with the
198-
`proc_macro_attribute` [attribute] that a signature of
199-
`(TokenStream, TokenStream) -> TokenStream`. The first [`TokenStream`] is the
200-
attribute's metaitems, not including the delimiters. If the attribute is written
201-
without a metaitem, the attribute [`TokenStream`] is empty. The second
202-
[`TokenStream`] is of the rest of the [item] including other [attributes] on the
203-
[item]. The returned [`TokenStream`] replaces the [item] with an arbitrary
204-
number of [items]. These macros cannot expand to syntax that defines new
205-
`macro_rule` style macros.
198+
`proc_macro_attribute` [attribute] that has a signature of `(TokenStream,
199+
TokenStream) -> TokenStream`. The first [`TokenStream`] is the delimited token
200+
tree following the attribute's name, not including the outer delimiters. If
201+
the attribute is written as a bare attribute name, the attribute
202+
[`TokenStream`] is empty. The second [`TokenStream`] is the rest of the [item]
203+
including other [attributes] on the [item]. The returned [`TokenStream`]
204+
replaces the [item] with an arbitrary number of [items]. These macros cannot
205+
expand to syntax that defines new `macro_rules` style macros.
206206

207207
For example, this attribute macro takes the input stream and returns it as is,
208208
effectively being the no-op of attributes.
@@ -247,16 +247,16 @@ fn invoke1() {}
247247
// out: attr: ""
248248
// out: item: "fn invoke1() { }"
249249
250-
// Example: Attribute has a metaitem
250+
// Example: Attribute with input
251251
#[show_streams(bar)]
252252
fn invoke2() {}
253253
// out: attr: "bar"
254254
// out: item: "fn invoke2() {}"
255255
256-
// Example: Multiple words in metaitem
257-
#[show_streams(multiple words)]
256+
// Example: Multiple tokens in the input
257+
#[show_streams(multiple => tokens)]
258258
fn invoke3() {}
259-
// out: attr: "multiple words"
259+
// out: attr: "multiple => tokens"
260260
// out: item: "fn invoke3() {}"
261261
262262
// Example:

src/type-layout.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The possible representations for a type are the default representation, `C`, the
116116
primitive representations, and `packed`. Multiple representations can be applied
117117
to a single type.
118118

119-
The representation of a type can be changed by applying the [`repr` attribute]
119+
The representation of a type can be changed by applying the `repr` attribute
120120
to it. The following example shows a struct with a `C` representation.
121121

122122
```
@@ -332,4 +332,4 @@ used with any other representation.
332332
[zero-variant enumerations]: items/enumerations.html#zero-variant-enums
333333
[undefined behavior]: behavior-considered-undefined.html
334334
[27060]: https://github.com/rust-lang/rust/issues/27060
335-
[`PhantomData<T>`]: special-types-and-traits.html#phantomdatat
335+
[`PhantomData<T>`]: special-types-and-traits.html#phantomdatat

0 commit comments

Comments
 (0)