From 771c5d10cf944bf7d221f5d6cb7abd2a06c400e4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 2 Oct 2019 18:41:44 -0700 Subject: [PATCH] Add macros in extern blocks and new proc-macro support. --- src/items/external-blocks.md | 10 +++++---- src/macros.md | 2 ++ src/procedural-macros.md | 42 +++++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index f3e692ac9576c..4a04093b77b17 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -8,9 +8,10 @@ >    `}` > > _ExternalItem_ :\ ->    [_OuterAttribute_]\*\ ->    [_Visibility_]?\ ->    ( _ExternalStaticItem_ | _ExternalFunctionItem_ ) +>    [_OuterAttribute_]\* (\ +>          [_MacroInvocationSemi_]\ +>       | ( [_Visibility_]? ( _ExternalStaticItem_ | _ExternalFunctionItem_ ) )\ +>    ) > > _ExternalStaticItem_ :\ >    `static` `mut`? [IDENTIFIER] `:` [_Type_] `;` @@ -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 @@ -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 diff --git a/src/macros.md b/src/macros.md index cdac0b2bfc519..f1ca1a9db6c81 100644 --- a/src/macros.md +++ b/src/macros.md @@ -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. @@ -99,3 +100,4 @@ example!(); [statements]: statements.md [types]: types.md [visibility qualifiers]: visibility-and-privacy.md +[External blocks]: items/external-blocks.md diff --git a/src/procedural-macros.md b/src/procedural-macros.md index 9818b26556e1a..34596e3959d3c 100644 --- a/src/procedural-macros.md +++ b/src/procedural-macros.md @@ -75,9 +75,7 @@ the macro invocation operator (`!`). These macros are defined by a [public] [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. @@ -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 @@ -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] [function] with the `proc_macro_attribute` [attribute] that has a signature of `(TokenStream, @@ -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. @@ -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