Skip to content

Commit

Permalink
Merge pull request #691 from ehuss/more-macros
Browse files Browse the repository at this point in the history
Add macros in extern blocks and new proc-macro support.
  • Loading branch information
Centril committed Oct 3, 2019
2 parents 62427fc + 771c5d1 commit 5b9d2fc
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 21 deletions.
10 changes: 6 additions & 4 deletions src/items/external-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
>    `}`
>
> _ExternalItem_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
> &nbsp;&nbsp; ( _ExternalStaticItem_ | _ExternalFunctionItem_ )
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_MacroInvocationSemi_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | ( [_Visibility_]<sup>?</sup> ( _ExternalStaticItem_ | _ExternalFunctionItem_ ) )\
> &nbsp;&nbsp; )
>
> _ExternalStaticItem_ :\
> &nbsp;&nbsp; `static` `mut`<sup>?</sup> [IDENTIFIER] `:` [_Type_] `;`
Expand All @@ -31,7 +32,7 @@
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
Expand Down Expand Up @@ -170,6 +171,7 @@ extern {
[_FunctionReturnType_]: functions.md
[_Generics_]: generics.md
[_InnerAttribute_]: ../attributes.md
[_MacroInvocationSemi_]: ../macros.md#macro-invocation
[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[_OuterAttribute_]: ../attributes.md
Expand Down
2 changes: 2 additions & 0 deletions src/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ following situations:
* [Types]
* [Items] including [associated items]
* [`macro_rules`] transcribers
* [External blocks]

When used as an item or a statement, the _MacroInvocationSemi_ form is used
where a semicolon is required at the end when not using curly braces.
Expand Down Expand Up @@ -99,3 +100,4 @@ example!();
[statements]: statements.md
[types]: types.md
[visibility qualifiers]: visibility-and-privacy.md
[External blocks]: items/external-blocks.md
42 changes: 25 additions & 17 deletions src/procedural-macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ the macro invocation operator (`!`).
These macros are defined by a [public]&#32;[function] with the `proc_macro`
[attribute] and a signature of `(TokenStream) -> TokenStream`. The input
[`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_rules` style macros.
output [`TokenStream`] replaces the entire macro invocation.
For example, the following macro definition ignores its input and outputs a
function `answer` into its scope.
Expand Down Expand Up @@ -105,11 +103,12 @@ fn main() {
}
```

These macros are only invokable in [modules]. They cannot even be invoked to
create [item declaration statements]. Furthermore, they must either be invoked
with curly braces and no semicolon or a different delimiter followed by a
semicolon. For example, `make_answer` from the previous example can be invoked
as `make_answer!{}`, `make_answer!();` or `make_answer![];`.
Function-like procedural macros may expand to a [type] or any number of
[items]. They may be invoked in a [type expression], [item] position (except
as a [statement]), including items in [`extern` blocks], inherent and trait
[implementations], and [trait definitions]. They cannot be used in a
[statement], [expression], or [pattern]. These macros cannot expand to syntax
that defines new [`macro_rules`] style macros.

### Derive macros

Expand Down Expand Up @@ -192,7 +191,9 @@ struct Struct {

### Attribute macros

*Attribute macros* define new [attributes] which can be attached to [items].
*Attribute macros* define new [outer attributes][attributes] which can be
attached to [items], including items in [`extern` blocks], inherent and trait
[implementations], and [trait definitions].

Attribute macros are defined by a [public]&#32;[function] with the
`proc_macro_attribute` [attribute] that has a signature of `(TokenStream,
Expand All @@ -202,7 +203,7 @@ 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.
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.
Expand Down Expand Up @@ -266,28 +267,35 @@ fn invoke4() {}
// out: item: "fn invoke4() {}"
```

[Attribute macros]: #attribute-macros
[Cargo's build scripts]: ../cargo/reference/build-scripts.html
[Derive macros]: #derive-macros
[Function-like macros]: #function-like-procedural-macros
[`TokenStream`]: ../proc_macro/struct.TokenStream.html
[`TokenStream`s]: ../proc_macro/struct.TokenStream.html
[`compile_error`]: ../std/macro.compile_error.html
[`derive` attribute]: attributes/derive.md
[`extern` blocks]: items/external-blocks.md
[`macro_rules`]: macros-by-example.md
[`proc_macro` crate]: ../proc_macro/index.html
[Cargo's build scripts]: ../cargo/reference/build-scripts.html
[Derive macros]: #derive-macros
[Attribute macros]: #attribute-macros
[Function-like macros]: #function-like-procedural-macros
[attribute]: attributes.md
[attributes]: attributes.md
[block]: expressions/block-expr.md
[crate type]: linkage.md
[derive macro helper attributes]: #derive-macro-helper-attributes
[enum]: items/enumerations.md
[expression]: expressions.md
[function]: items/functions.md
[implementations]: items/implementations.md
[inert]: attributes.md#active-and-inert-attributes
[item]: items.md
[item declaration statements]: statements.md#item-declarations
[items]: items.md
[function]: items/functions.md
[module]: items/modules.md
[modules]: items/modules.md
[pattern]: patterns.md
[public]: visibility-and-privacy.md
[statement]: statements.md
[struct]: items/structs.md
[trait definitions]: items/traits.md
[type expression]: types.md#type-expressions
[type]: types.md
[union]: items/unions.md

0 comments on commit 5b9d2fc

Please sign in to comment.