Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attributes in generics position and general attributes improvements #350

Merged
merged 1 commit into from
Jun 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
>    | _MetaItem_
>    | _MetaItem_ `,` _MetaSeq_

Any item declaration may have an _attribute_ applied to it. Attributes in Rust
are modeled on Attributes in ECMA-335, with the syntax coming from ECMA-334
(C#). An attribute is a general, free-form metadatum that is interpreted
according to name, convention, and language and compiler version. Attributes
may appear as any of:
Any [item declaration] or [generic lifetime or type parameter][generics] may
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or statement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or block expression

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this is a lot more complicated, because also enum variants, struct and union fields, match arms...

have an attribute applied to it. Attributes are modeled on Attributes in
[ECMA-335], with the syntax coming from [ECMA-334] \(C#). An _attribute_ is a
general, free-form metadatum that is interpreted according to name, convention,
and language and compiler version. Attributes may appear as any of:

* A single identifier, the attribute name
* An identifier followed by the equals sign '=' and a literal, providing a
Expand All @@ -34,9 +34,10 @@ may appear as any of:
key/value pair
* An identifier followed by a parenthesized list of sub-attribute arguments

Attributes with a bang ("!") after the hash ("#") apply to the item that the
attribute is declared within. Attributes that do not have a bang after the hash
apply to the item that follows the attribute.
_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 item or generic parameter that follow the
attribute.

An example of attributes:

Expand Down Expand Up @@ -101,7 +102,8 @@ type int8_t = i8;
- `test` - indicates that this function is a test function, to only be compiled
in case of `--test`.
- `ignore` - indicates that this test function is disabled.
- `should_panic` - indicates that this test function should panic, inverting the success condition.
- `should_panic` - indicates that this test function should panic, inverting the
success condition.
- `cold` - The function is unlikely to be executed, so optimize it (and calls
to it) differently.

Expand Down Expand Up @@ -153,9 +155,9 @@ which can be used to control type layout.
- `no_link` on an `extern crate` — even if we load this crate for macros, don't
link it into the output.

See the [macros section of the
book](../book/first-edition/macros.html#scoping-and-macro-importexport) for more information on
macro scope.
See the [macros section of the first edition of the
book](../book/first-edition/macros.html#scoping-and-macro-importexport) for more
information on macro scope.

## Miscellaneous attributes

Expand Down Expand Up @@ -213,8 +215,8 @@ release builds.
Configuration options are boolean (on or off) and are named either with a
single identifier (e.g. `foo`) or an identifier and a string (e.g. `foo = "bar"`;
the quotes are required and spaces around the `=` are unimportant). Note that
similarly-named options, such as `foo`, `foo="bar"` and `foo="baz"` may each be set
or unset independently.
similarly-named options, such as `foo`, `foo="bar"` and `foo="baz"` may each be
set or unset independently.

Configuration options are either provided by the compiler or passed in on the
command line using `--cfg` (e.g. `rustc main.rs --cfg foo --cfg 'bar="baz"'`).
Expand Down Expand Up @@ -537,3 +539,7 @@ You can implement `derive` for your own type through [procedural macros].
[let statement]: statements.html#let-statements
[unstable book plugin]: ../unstable-book/language-features/plugin.html#lint-plugins
[zero-variant enum]: items/enumerations.html#zero-variant-enums
[ECMA-334]: https://www.ecma-international.org/publications/standards/Ecma-334.htm
[ECMA-335]: https://www.ecma-international.org/publications/standards/Ecma-335.htm
[item declaration]: items.html
[generics]: generics.html
23 changes: 21 additions & 2 deletions src/items/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
> &nbsp;&nbsp; ( _LifetimeParam_ `,` )<sup>\*</sup> _LifetimeParam_<sup>?</sup>
>
> _LifetimeParam_ :
> &nbsp;&nbsp; [LIFETIME_OR_LABEL] `:` [_LifetimeBounds_]<sup>?</sup>
> &nbsp;&nbsp; [_OuterAttribute_]<sup>?</sup> [LIFETIME_OR_LABEL] `:` [_LifetimeBounds_]<sup>?</sup>
>
> _TypeParams_:
> &nbsp;&nbsp; ( _TypeParam_ `,` )<sup>\*</sup> _TypeParam_ <sup>?</sup>
>
> _TypeParam_ :
> &nbsp;&nbsp; [IDENTIFIER] ( `:` [_TypeParamBounds_] )<sup>?</sup> ( `=` [_Type_] )<sup>?</sup>
> &nbsp;&nbsp; [_OuterAttribute_]<sup>?</sup> [IDENTIFIER] ( `:` [_TypeParamBounds_] )<sup>?</sup> ( `=` [_Type_] )<sup>?</sup>

Functions, type aliases, structs, enumerations, unions, traits and
implementations may be *parameterized* by types and lifetimes. These parameters
Expand Down Expand Up @@ -83,11 +83,29 @@ where
}
```

## Attributes

Generic lifetime and type parameters allow [attributes] on them. There are no
built-in attributes that do anything in this position, although custom derive
attributes may give meaning to it.

This example shows using a custom derive attribute to modify the meaning of a
generic parameter.

```ignore
// Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as
// an attribute it understands.
#[derive(MyFlexibleClone)] struct Foo<#[my_flexible_clone(unbounded)] H> {
a: *const H
}
```

[IDENTIFIER]: identifiers.html
[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels

[_LifetimeBounds_]: trait-bounds.html
[_Lifetime_]: trait-bounds.html
[_OuterAttribute_]: attributes.html
[_Type_]: types.html
[_TypeParamBounds_]: trait-bounds.html

Expand All @@ -100,6 +118,7 @@ where
[`Sized`]: special-types-and-traits.html#sized
[tuples]: types.html#tuple-types
[trait object]: types.html#trait-objects
[attributes]: attributes.html

[path]: ../paths.html
[Trait]: traits.html#trait-bounds
Expand Down