diff --git a/src/attributes.md b/src/attributes.md
index bbd809f99..32d555c9e 100644
--- a/src/attributes.md
+++ b/src/attributes.md
@@ -1,44 +1,39 @@
# Attributes
> **Syntax**\
-> _Attribute_ :\
-> _InnerAttribute_ | _OuterAttribute_
->
> _InnerAttribute_ :\
-> `#![` MetaItem `]`
+> `#` `!` `[` _Attr_ `]`
>
> _OuterAttribute_ :\
-> `#[` MetaItem `]`
->
-> _MetaItem_ :\
-> [_SimplePath_]\
-> | [_SimplePath_] `=` [_LiteralExpression_]_without suffix_\
-> | [_SimplePath_] `(` _MetaSeq_? `)`
+> `#` `[` _Attr_ `]`
>
-> _MetaSeq_ :\
-> _MetaItemInner_ ( `,` MetaItemInner )\* `,`?
+> _Attr_ :\
+> [_SimplePath_] _AttrInput_?
>
-> _MetaItemInner_ :\
-> _MetaItem_\
-> | [_LiteralExpression_]_without suffix_
+> _AttrInput_ :\
+> [_DelimTokenTree_]\
+> | `=` [_LiteralExpression_]_without suffix_
An _attribute_ is a general, free-form metadatum that is interpreted according
to name, convention, and language and compiler version. Attributes are modeled
on Attributes in [ECMA-335], with the syntax coming from [ECMA-334] \(C#).
-Attributes may appear as any of:
+_Inner attributes_, written with a bang (`!`) after the hash (`#`), apply to the
+item that the attribute is declared within. _Outer attributes_, written without
+the bang after the hash, apply to the thing that follows the attribute.
-* A single identifier, the _attribute name_
-* An identifier followed by the equals sign '=' and a literal, providing a
- key/value pair
-* An identifier followed by a parenthesized list of sub-attribute arguments
- which include literals
+The attribute consists of a path to the attribute, followed by an optional
+delimited token tree whose interpretation is defined by the attribute.
+Attributes other than macro attributes also allow the input to be an equals
+sign (`=`) followed by a literal expression. See the [meta item
+syntax](#meta-item-attribute-syntax) below for more details.
-Literal values must not include integer or float type suffixes.
+Attributes can be classified into the following kinds:
-_Inner attributes_, written with a bang ("!") after the hash ("#"), apply to the
-item that the attribute is declared within. _Outer attributes_, written without
-the bang after the hash, apply to the thing that follows the attribute.
+* Built-in attributes
+* [Macro attributes][attribute macro]
+* [Derive macro helper attributes]
+* [Tool attributes](#tool-attributes)
Attributes may be applied to many things in the language:
@@ -87,11 +82,34 @@ fn some_unused_variables() {
}
```
-There are three kinds of attributes:
+## Meta Item Attribute Syntax
-* Built-in attributes
-* Macro attributes
-* Derive macro helper attributes
+A "meta item" is the syntax used for the _Attr_ rule by most built-in
+attributes and the [`meta` macro fragment specifier]. It has the following
+grammar:
+
+> **Syntax**\
+> _MetaItem_ :\
+> [_SimplePath_]\
+> | [_SimplePath_] `=` [_LiteralExpression_]_without suffix_\
+> | [_SimplePath_] `(` _MetaSeq_? `)`
+>
+> _MetaSeq_ :\
+> _MetaItemInner_ ( `,` MetaItemInner )\* `,`?
+>
+> _MetaItemInner_ :\
+> _MetaItem_\
+> | [_LiteralExpression_]_without suffix_
+
+Literal expressions in meta items must not include integer or float type
+suffixes.
+
+Some examples of meta items are:
+- `no_std`
+- `doc = "example"`
+- `cfg(any())`
+- `deprecated(since = "1.2.0", note = "text")`
+- `repr(align(32))`
## Active and inert attributes
@@ -139,28 +157,18 @@ names have meaning.
On an `extern` block, the following attributes are interpreted:
-- `link_args` - specify arguments to the linker, rather than just the library
- name and type. This is feature gated and the exact behavior is
- implementation-defined (due to variety of linker invocation syntax).
- `link` - indicate that a native library should be linked to for the
declarations in this block to be linked correctly. `link` supports an optional
`kind` key with three possible values: `dylib`, `static`, and `framework`. See
[external blocks](items/external-blocks.html) for more about external blocks.
Two examples: `#[link(name = "readline")]` and
`#[link(name = "CoreFoundation", kind = "framework")]`.
-- `linked_from` - indicates what native library this block of FFI items is
- coming from. This attribute is of the form `#[linked_from = "foo"]` where
- `foo` is the name of a library in either `#[link]` or a `-l` flag. This
- attribute is currently required to export symbols from a Rust dynamic library
- on Windows, and it is feature gated behind the `linked_from` feature.
On declarations inside an `extern` block, the following attributes are
interpreted:
- `link_name` - the name of the symbol that this function or static should be
imported as.
-- `linkage` - on a static, this specifies the [linkage
- type](http://llvm.org/docs/LangRef.html#linkage-types).
See [type layout](type-layout.html) for documentation on the `repr` attribute
which can be used to control type layout.
@@ -175,8 +183,6 @@ which can be used to control type layout.
macros named. The `extern crate` must appear at the crate root, not inside
`mod`, which ensures proper function of the `$crate` macro variable.
-- `macro_reexport` on an `extern crate` — re-export the named macros.
-
- `macro_export` - export a `macro_rules` macro for cross-crate usage.
- `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
Otherwise, they work just like regular lint attributes:
-
-```rust,ignore
+```rust
// set the entire `pedantic` clippy lint group to warn
#![warn(clippy::pedantic)]
// silence warnings from the `filter_map` clippy lint
@@ -552,6 +557,34 @@ impl PartialEq for Foo {
You can implement `derive` for your own traits through [procedural macros].
+## Tool attributes
+
+The compiler may allow attributes for external tools where each tool resides
+in its own namespace. The first segment of the attribute path is the name of
+the tool, with one or more additional segments whose interpretation is up to
+the tool.
+
+When a tool is not in use, the tool's attributes are accepted without a
+warning. When the tool is in use, the tool is responsible for processing and
+interpretation of its attributes.
+
+Tool attributes are not available if the [`no_implicit_prelude`] attribute is
+used.
+
+```rust
+// Tells the rustfmt tool to not format the following element.
+#[rustfmt::skip]
+struct S {
+}
+
+// Controls the "cyclomatic complexity" threshold for the clippy tool.
+#[clippy::cyclomatic_complexity = "100"]
+pub fn f() {}
+```
+
+> Note: `rustc` currently recognizes the tools "clippy" and "rustfmt".
+
+[_DelimTokenTree_]: macros.html
[_LiteralExpression_]: expressions/literal-expr.html
[_SimplePath_]: paths.html#simple-paths
[`no_implicit_prelude`]: items/modules.html#prelude-items
@@ -585,6 +618,7 @@ You can implement `derive` for your own traits through [procedural macros].
[external blocks]: items/external-blocks.html
[items]: items.html
[attribute macro]: procedural-macros.html#attribute-macros
+[derive macro helper attributes]: procedural-macros.html#derive-macro-helper-attributes
[function-like macro]: procedural-macros.html#function-like-procedural-macros
[conditional compilation]: conditional-compilation.html
[derive macro]: procedural-macros.html#derive-macros
@@ -594,3 +628,4 @@ You can implement `derive` for your own traits through [procedural macros].
[where clause]: items/where-clauses.html
[trait or lifetime bounds]: trait-bounds.html
[Expression Attributes]: expressions.html#expression-attributes
+[`meta` macro fragment specifier]: macros-by-example.html
diff --git a/src/conditional-compilation.md b/src/conditional-compilation.md
index 8044db217..760f1d862 100644
--- a/src/conditional-compilation.md
+++ b/src/conditional-compilation.md
@@ -104,7 +104,7 @@ Example values:
* `"android"`
* `"freebsd"`
* `"dragonfly"`
-* `"bitrig"`
+* `"bitrig"`
* `"openbsd"`
* `"netbsd"`
@@ -151,7 +151,7 @@ Key-value option set once with the target's pointer width in bits. For example,
for targets with 32-bit pointers, this is set to `"32"`. Likewise, it is set
to `"64"` for targets with 64-bit pointers.
-
+
### `target_vendor`
@@ -235,16 +235,16 @@ generic parameters.
> **Syntax**\
> _CfgAttrAttribute_ :\
-> `cfg_attr` `(` _ConfigurationPredicate_ `,` [_MetaItem_] `,`? `)`
+> `cfg_attr` `(` _ConfigurationPredicate_ `,` _CfgAttrs_? `)`
+>
+> _CfgAttrs_ :\
+> [_Attr_] (`,` [_Attr_])\* `,`?
The `cfg_attr` [attribute] conditionally includes [attributes] based on a
configuration predicate.
-It is written as `cfg_attr` followed by `(`, a configuration predicate, a
-[metaitem], an optional `,`, and finally a `)`.
-
-When the configuration predicate is true, this attribute expands out to be an
-attribute of the attribute metaitem. For example, the following module will
+When the configuration predicate is true, this attribute expands out to the
+attributes listed after the predicate. For example, the following module will
either be found at `linux.rs` or `windows.rs` based on the target.
```rust,ignore
@@ -253,6 +253,19 @@ either be found at `linux.rs` or `windows.rs` based on the target.
mod os;
```
+Zero, one, or more attributes may be listed. Multiple attributes will each be
+expanded into separate attributes. For example:
+
+```rust,ignore
+#[cfg_attr(feature = "magic", sparkles, crackles)]
+fn bewitched() {}
+
+// When the `magic` feature flag is enabled, the above will expand to:
+#[sparkles]
+#[crackles]
+fn bewitched() {}
+```
+
> **Note**: The `cfg_attr` can expand to another `cfg_attr`. For example,
> `#[cfg_attr(linux, cfg_attr(feature = "multithreaded", some_other_attribute))`
> is valid. This example would be equivalent to
@@ -284,7 +297,7 @@ println!("I'm running on a {} machine!", machine_kind);
[IDENTIFIER]: identifiers.html
[RAW_STRING_LITERAL]: tokens.html#raw-string-literals
[STRING_LITERAL]: tokens.html#string-literals
-[_MetaItem_]: attributes.html
+[_Attr_]: attributes.html
[`--cfg`]: ../rustc/command-line-arguments.html#a--cfg-configure-the-compilation-environment
[`--test`]: ../rustc/command-line-arguments.html#a--test-build-a-test-harness
[`cfg`]: #the-cfg-attribute
@@ -296,4 +309,3 @@ println!("I'm running on a {} machine!", machine_kind);
[crate type]: linkage.html
[expressions]: expressions.html
[items]: items.html
-[metaitem]: attributes.html
diff --git a/src/macros-by-example.md b/src/macros-by-example.md
index c62e357c0..8156114a1 100644
--- a/src/macros-by-example.md
+++ b/src/macros-by-example.md
@@ -80,7 +80,7 @@ syntax named by _designator_. Valid designators are:
[_Expression_]: expressions.html
[_Item_]: items.html
[_LiteralExpression_]: expressions/literal-expr.html
-[_MetaItem_]: attributes.html
+[_MetaItem_]: attributes.html#meta-item-attribute-syntax
[_Pattern_]: patterns.html
[_Statement_]: statements.html
[_TokenTree_]: macros.html#macro-invocation
diff --git a/src/procedural-macros.md b/src/procedural-macros.md
index 6875e908f..d788b7ad0 100644
--- a/src/procedural-macros.md
+++ b/src/procedural-macros.md
@@ -77,7 +77,7 @@ These macros are defined by a [public] [function] with the `proc_macro`
[`TokenStream`] is what is inside the delimiters of the macro invocation and the
output [`TokenStream`] replaces the entire macro invocation. It may contain an
arbitrary number of [items]. These macros cannot expand to syntax that defines
-new `macro_rule` style macros.
+new `macro_rules` style macros.
For example, the following macro definition ignores its input and outputs a
function `answer` into its scope.
@@ -195,14 +195,14 @@ struct Struct {
*Attribute macros* define new [attributes] which can be attached to [items].
Attribute macros are defined by a [public] [function] with the
-`proc_macro_attribute` [attribute] that a signature of
-`(TokenStream, TokenStream) -> TokenStream`. The first [`TokenStream`] is the
-attribute's metaitems, not including the delimiters. If the attribute is written
-without a metaitem, the attribute [`TokenStream`] is empty. The second
-[`TokenStream`] is of the rest of the [item] including other [attributes] on the
-[item]. The returned [`TokenStream`] replaces the [item] with an arbitrary
-number of [items]. These macros cannot expand to syntax that defines new
-`macro_rule` style macros.
+`proc_macro_attribute` [attribute] that has a signature of `(TokenStream,
+TokenStream) -> TokenStream`. The first [`TokenStream`] is the delimited token
+tree following the attribute's name, not including the outer delimiters. If
+the attribute is written as a bare attribute name, the attribute
+[`TokenStream`] is empty. The second [`TokenStream`] is the rest of the [item]
+including other [attributes] on the [item]. The returned [`TokenStream`]
+replaces the [item] with an arbitrary number of [items]. These macros cannot
+expand to syntax that defines new `macro_rules` style macros.
For example, this attribute macro takes the input stream and returns it as is,
effectively being the no-op of attributes.
@@ -247,16 +247,16 @@ fn invoke1() {}
// out: attr: ""
// out: item: "fn invoke1() { }"
-// Example: Attribute has a metaitem
+// Example: Attribute with input
#[show_streams(bar)]
fn invoke2() {}
// out: attr: "bar"
// out: item: "fn invoke2() {}"
-// Example: Multiple words in metaitem
-#[show_streams(multiple words)]
+// Example: Multiple tokens in the input
+#[show_streams(multiple => tokens)]
fn invoke3() {}
-// out: attr: "multiple words"
+// out: attr: "multiple => tokens"
// out: item: "fn invoke3() {}"
// Example:
diff --git a/src/type-layout.md b/src/type-layout.md
index c746855fa..9d56851bd 100644
--- a/src/type-layout.md
+++ b/src/type-layout.md
@@ -116,7 +116,7 @@ The possible representations for a type are the default representation, `C`, the
primitive representations, and `packed`. Multiple representations can be applied
to a single type.
-The representation of a type can be changed by applying the [`repr` attribute]
+The representation of a type can be changed by applying the `repr` attribute
to it. The following example shows a struct with a `C` representation.
```
@@ -332,4 +332,4 @@ used with any other representation.
[zero-variant enumerations]: items/enumerations.html#zero-variant-enums
[undefined behavior]: behavior-considered-undefined.html
[27060]: https://github.com/rust-lang/rust/issues/27060
-[`PhantomData`]: special-types-and-traits.html#phantomdatat
\ No newline at end of file
+[`PhantomData`]: special-types-and-traits.html#phantomdatat