From 99c96cdabc8507ca5ea0fcb69af03d75cd7b48a4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 07:17:28 -0700 Subject: [PATCH 01/10] Unwrap macro_export --- src/macros-by-example.md | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index b1c585da7a..f5317ba37f 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -372,9 +372,7 @@ r[macro.decl.scope.path] ### Path-based scope r[macro.decl.scope.path.intro] -By default, a macro has no path-based scope. However, if it has the -`#[macro_export]` attribute, then it is declared in the crate root scope and can -be referred to normally as such: +By default, a macro has no path-based scope. However, if it has the `#[macro_export]` attribute, then it is declared in the crate root scope and can be referred to normally as such: ```rust self::m!(); @@ -394,8 +392,7 @@ mod mac { ``` r[macro.decl.scope.path.export] -Macros labeled with `#[macro_export]` are always `pub` and can be referred to -by other crates, either by path or by `#[macro_use]` as described above. +Macros labeled with `#[macro_export]` are always `pub` and can be referred to by other crates, either by path or by `#[macro_use]` as described above. r[macro.decl.hygiene] ## Hygiene @@ -495,20 +492,11 @@ macro_rules! call_foo { fn foo() {} ``` -> **Version differences**: Prior to Rust 1.30, `$crate` and -> `local_inner_macros` (below) were unsupported. They were added alongside -> path-based imports of macros (described above), to ensure that helper macros -> did not need to be manually imported by users of a macro-exporting crate. -> Crates written for earlier versions of Rust that use helper macros need to be -> modified to use `$crate` or `local_inner_macros` to work well with path-based -> imports. +> [!NOTE] +> Prior to Rust 1.30, `$crate` and `local_inner_macros` (below) were unsupported. They were added alongside path-based imports of macros (described above), to ensure that helper macros did not need to be manually imported by users of a macro-exporting crate. Crates written for earlier versions of Rust that use helper macros need to be modified to use `$crate` or `local_inner_macros` to work well with path-based imports. r[macro.decl.hygiene.local_inner_macros] -When a macro is exported, the `#[macro_export]` attribute can have the -`local_inner_macros` keyword added to automatically prefix all contained macro -invocations with `$crate::`. This is intended primarily as a tool to migrate -code written before `$crate` was added to the language to work with Rust 2018's -path-based imports of macros. Its use is discouraged in new code. +When a macro is exported, the `#[macro_export]` attribute can have the `local_inner_macros` keyword added to automatically prefix all contained macro invocations with `$crate::`. This is intended primarily as a tool to migrate code written before `$crate` was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code. ```rust #[macro_export(local_inner_macros)] From 08d31ecb45dfb637297eea303d5da4efbc09b989 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:05:03 -0700 Subject: [PATCH 02/10] Rename "Path-Based Scope" section title This renames the section title to "The `macro_export` attribute" to follow the attribute template. Although I like the old title, since it describes what it does, I would prefer to not make exceptions and stay consistent. --- book.toml | 1 + src/attributes.md | 2 +- src/macros-by-example.md | 6 +++--- src/names.md | 2 +- src/names/scopes.md | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/book.toml b/book.toml index d02ccde184..e4dced2e64 100644 --- a/book.toml +++ b/book.toml @@ -33,6 +33,7 @@ use-boolean-and = true "/items/modules.html#prelude-items" = "../names/preludes.html" "/items/traits.html#object-safety" = "traits.html#dyn-compatibility" "/lifetime-elision.html#static-lifetime-elision" = "lifetime-elision.html#const-and-static-elision" +"/macros-by-example.html#path-based-scope" = "macros-by-example.html#the-macro_export-attribute" "/procedural-macros.html#derive-macros" = "procedural-macros.html#the-proc_macro_derive-attribute" "/runtime.html#the-panic_handler-attribute" = "panic.html#the-panic_handler-attribute" "/unsafe-blocks.html" = "unsafe-keyword.html" diff --git a/src/attributes.md b/src/attributes.md index 53ce86a443..a2a927bef0 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -359,7 +359,7 @@ The following is an index of all built-in attributes. [`link_ordinal`]: items/external-blocks.md#the-link_ordinal-attribute [`link_section`]: abi.md#the-link_section-attribute [`link`]: items/external-blocks.md#the-link-attribute -[`macro_export`]: macros-by-example.md#path-based-scope +[`macro_export`]: macros-by-example.md#the-macro_export-attribute [`macro_use`]: macros-by-example.md#the-macro_use-attribute [`must_use`]: attributes/diagnostics.md#the-must_use-attribute [`naked`]: attributes/codegen.md#the-naked-attribute diff --git a/src/macros-by-example.md b/src/macros-by-example.md index f5317ba37f..88577fdb37 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -368,11 +368,11 @@ r[macro.decl.scope.macro_use.export] Macros to be imported with `#[macro_use]` must be exported with `#[macro_export]`, which is described below. -r[macro.decl.scope.path] -### Path-based scope +r[macro.decl.scope.macro_export] +### The `macro_export` attribute -r[macro.decl.scope.path.intro] By default, a macro has no path-based scope. However, if it has the `#[macro_export]` attribute, then it is declared in the crate root scope and can be referred to normally as such: +r[macro.decl.scope.macro_export.intro] ```rust self::m!(); diff --git a/src/names.md b/src/names.md index b9af0e5359..a714728b9a 100644 --- a/src/names.md +++ b/src/names.md @@ -137,7 +137,7 @@ to with certain [path qualifiers] or aliases. [`for`]: expressions/loop-expr.md#iterator-loops [`if let`]: expressions/if-expr.md#if-let-patterns [`let` statement]: statements.md#let-statements -[`macro_export` attribute]: macros-by-example.md#path-based-scope +[`macro_export` attribute]: macros-by-example.md#the-macro_export-attribute [`macro_rules` declarations]: macros-by-example.md [`macro_use` attribute]: macros-by-example.md#the-macro_use-attribute [`match`]: expressions/match-expr.md diff --git a/src/names/scopes.md b/src/names/scopes.md index 0a7240512f..382aa29241 100644 --- a/src/names/scopes.md +++ b/src/names/scopes.md @@ -343,7 +343,7 @@ impl ImplExample { [`if let`]: ../expressions/if-expr.md#if-let-patterns [`while let`]: ../expressions/loop-expr.md#while-let-patterns [`let` statement]: ../statements.md#let-statements -[`macro_export`]: ../macros-by-example.md#path-based-scope +[`macro_export`]: ../macros-by-example.md#the-macro_export-attribute [`macro_use` prelude]: preludes.md#macro_use-prelude [`macro_use`]: ../macros-by-example.md#the-macro_use-attribute [`match` arms]: ../expressions/match-expr.md From c81355ab7fa87fec8a3ef2c86f2832e2f3b53bcb Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:05:25 -0700 Subject: [PATCH 03/10] Link to macro_export --- src/macros-by-example.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 88577fdb37..9a9f49f69a 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -365,8 +365,8 @@ lazy_static!{} ``` r[macro.decl.scope.macro_use.export] -Macros to be imported with `#[macro_use]` must be exported with -`#[macro_export]`, which is described below. +Macros to be imported with `macro_use` must be exported with +[`macro_export`][macro.decl.scope.macro_export]. r[macro.decl.scope.macro_export] ### The `macro_export` attribute From 7600e94383fd747e662b9e67e85497e09c7f6ee0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:06:48 -0700 Subject: [PATCH 04/10] Move example to an example block --- src/macros-by-example.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 9a9f49f69a..75258a379e 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -374,25 +374,26 @@ r[macro.decl.scope.macro_export] By default, a macro has no path-based scope. However, if it has the `#[macro_export]` attribute, then it is declared in the crate root scope and can be referred to normally as such: r[macro.decl.scope.macro_export.intro] -```rust -self::m!(); -m!(); // OK: Path-based lookup finds m in the current module. - -mod inner { - super::m!(); - crate::m!(); -} - -mod mac { - #[macro_export] - macro_rules! m { - () => {}; - } -} -``` r[macro.decl.scope.path.export] Macros labeled with `#[macro_export]` are always `pub` and can be referred to by other crates, either by path or by `#[macro_use]` as described above. +> [!EXAMPLE] +> ```rust +> self::m!(); +> m!(); // OK: Path-based lookup finds m in the current module. +> +> mod inner { +> super::m!(); +> crate::m!(); +> } +> +> mod mac { +> #[macro_export] +> macro_rules! m { +> () => {}; +> } +> } +> ``` r[macro.decl.hygiene] ## Hygiene From 57af92aa09aef3f701b8019fd46a13eca3fbd3c9 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:07:28 -0700 Subject: [PATCH 05/10] Reword macro.decl.scope.macro_export.intro Rewording to follow the template, and to try to be a little clearer. --- src/macros-by-example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 75258a379e..f67685c319 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -371,8 +371,8 @@ Macros to be imported with `macro_use` must be exported with r[macro.decl.scope.macro_export] ### The `macro_export` attribute -By default, a macro has no path-based scope. However, if it has the `#[macro_export]` attribute, then it is declared in the crate root scope and can be referred to normally as such: r[macro.decl.scope.macro_export.intro] +The *`macro_export` [attribute][attributes]* marks a macro to be publicly exported from the crate, and makes it available in the root of the crate for path-based resolution. r[macro.decl.scope.path.export] From f87345356e6052467e905265f3afc67892684f51 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:07:55 -0700 Subject: [PATCH 06/10] Add macro_export template rules --- src/macros-by-example.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index f67685c319..a904f885a1 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -395,6 +395,21 @@ Macros labeled with `#[macro_export]` are always `pub` and can be referred to by > } > ``` +r[macro.decl.scope.macro_export.syntax] +The `macro_export` attribute uses the [MetaWord] syntax, or the [MetaListIdents] syntax with a single value of [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros]. + +r[macro.decl.scope.macro_export.allowed-positions] +The `macro_export` attribute can be applied to `macro_rules` definitions. + +> [!NOTE] +> `rustc` currently warns in other positions, but this may be rejected in the future. + +r[macro.decl.scope.macro_export.duplicates] +Only the first instance of `macro_export` on a macro is honored. Subsequent `macro_export` attributes are ignored. + +> [!NOTE] +> `rustc` currently warns on subsequent duplicate `macro_export` attributes. + r[macro.decl.hygiene] ## Hygiene From 9a901513749037b819e90c5b1a1fdad8c0550bde Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:08:45 -0700 Subject: [PATCH 07/10] Add some more explicit macro_export rules This adds more rules to be a little more explicit about the behavior, along with some examples. --- src/macros-by-example.md | 50 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index a904f885a1..1f23392598 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -374,9 +374,6 @@ r[macro.decl.scope.macro_export] r[macro.decl.scope.macro_export.intro] The *`macro_export` [attribute][attributes]* marks a macro to be publicly exported from the crate, and makes it available in the root of the crate for path-based resolution. - -r[macro.decl.scope.path.export] -Macros labeled with `#[macro_export]` are always `pub` and can be referred to by other crates, either by path or by `#[macro_use]` as described above. > [!EXAMPLE] > ```rust > self::m!(); @@ -410,6 +407,53 @@ Only the first instance of `macro_export` on a macro is honored. Subsequent `mac > [!NOTE] > `rustc` currently warns on subsequent duplicate `macro_export` attributes. +r[macro.decl.scope.macro_export.path-based] +By default, macros only have [textually-based scoping](#textual-scope). When the `macro_export` attribute is used, the macro is reexported in the crate root, and can be referred to using a path to the macro in the crate root. + +r[macro.decl.scope.macro_export.export] +The `macro_export` attribute causes a macro to be publicly exported from the crate root so that it can be referred to by other crates using a path. + +> [!EXAMPLE] +> Given the following defined in a crate named `log`: +> ```rust +> #[macro_export] +> macro_rules! warn { +> ($message:expr) => { eprintln!("WARN: {}", $message) }; +> } +> ``` +> Then you can refer to the macro via a path to the crate: +> +> ```rust,ignore +> fn main() { +> log::warn!("example warning"); +> } +> ``` + +r[macro.decl.scope.macro_export.macro_use] +`macro_export` also allows the use of [`macro_use`][macro.decl.scope.macro_use] on an `extern crate` to import the macro into the [`macro_use` prelude]. + +> [!EXAMPLE] +> Given the following defined in a crate named `log`: +> ```rust +> #[macro_export] +> macro_rules! warn { +> ($message:expr) => { eprintln!("WARN: {}", $message) }; +> } +> ``` +> Using `macro_use` in a dependent crate means the macro can be used from the prelude: +> +> ```rust,ignore +> #[macro_use] +> extern crate log; +> +> pub mod util { +> pub fn do_thing() { +> // Resolved via macro prelude. +> warn!("example warning"); +> } +> } +> ``` + r[macro.decl.hygiene] ## Hygiene From db5285fe40a63970fbd47ca167f6e1b7e5b6624a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 11 Jun 2025 11:10:30 -0700 Subject: [PATCH 08/10] Rewrite local_inner_macros This moves it to the macro_export section (since it is part of that macro). There are slight wording differences. One new addition is to clarify that it only works for single-segment paths. --- src/macros-by-example.md | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 1f23392598..185334ac03 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -396,7 +396,7 @@ r[macro.decl.scope.macro_export.syntax] The `macro_export` attribute uses the [MetaWord] syntax, or the [MetaListIdents] syntax with a single value of [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros]. r[macro.decl.scope.macro_export.allowed-positions] -The `macro_export` attribute can be applied to `macro_rules` definitions. +The `macro_export` attribute may be applied to `macro_rules` definitions. > [!NOTE] > `rustc` currently warns in other positions, but this may be rejected in the future. @@ -454,6 +454,22 @@ r[macro.decl.scope.macro_export.macro_use] > } > ``` +r[macro.decl.scope.macro_export.local_inner_macros] +Adding `local_inner_macros` to the `macro_export` attribute also causes all single-segment macro invocations in the macro definition to have an implicit `$crate::` prefix. This is intended primarily as a tool to migrate code written before [`$crate`] was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code. + +> [!EXAMPLE] +> ```rust +> #[macro_export(local_inner_macros)] +> macro_rules! helped { +> () => { helper!() } // Automatically converted to $crate::helper!(). +> } +> +> #[macro_export] +> macro_rules! helper { +> () => { () } +> } +> ``` + r[macro.decl.hygiene] ## Hygiene @@ -553,22 +569,7 @@ fn foo() {} ``` > [!NOTE] -> Prior to Rust 1.30, `$crate` and `local_inner_macros` (below) were unsupported. They were added alongside path-based imports of macros (described above), to ensure that helper macros did not need to be manually imported by users of a macro-exporting crate. Crates written for earlier versions of Rust that use helper macros need to be modified to use `$crate` or `local_inner_macros` to work well with path-based imports. - -r[macro.decl.hygiene.local_inner_macros] -When a macro is exported, the `#[macro_export]` attribute can have the `local_inner_macros` keyword added to automatically prefix all contained macro invocations with `$crate::`. This is intended primarily as a tool to migrate code written before `$crate` was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code. - -```rust -#[macro_export(local_inner_macros)] -macro_rules! helped { - () => { helper!() } // Automatically converted to $crate::helper!(). -} - -#[macro_export] -macro_rules! helper { - () => { () } -} -``` +> Prior to Rust 1.30, `$crate` and [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros] were unsupported. They were added alongside [path-based imports of macros][macro.decl.scope.macro_export], to ensure that helper macros did not need to be manually imported by users of a macro-exporting crate. Crates written for earlier versions of Rust that use helper macros need to be modified to use `$crate` or `local_inner_macros` to work well with path-based imports. r[macro.decl.follow-set] ## Follow-set ambiguity restrictions From d0405834f1a7e774f11d09bbc5fd86a3841b33fe Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 7 Oct 2025 13:40:11 -0700 Subject: [PATCH 09/10] Update macro_use for updated attribute template --- src/macros-by-example.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 185334ac03..8411b8b18d 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -368,6 +368,7 @@ r[macro.decl.scope.macro_use.export] Macros to be imported with `macro_use` must be exported with [`macro_export`][macro.decl.scope.macro_export]. + r[macro.decl.scope.macro_export] ### The `macro_export` attribute @@ -399,13 +400,13 @@ r[macro.decl.scope.macro_export.allowed-positions] The `macro_export` attribute may be applied to `macro_rules` definitions. > [!NOTE] -> `rustc` currently warns in other positions, but this may be rejected in the future. +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. r[macro.decl.scope.macro_export.duplicates] -Only the first instance of `macro_export` on a macro is honored. Subsequent `macro_export` attributes are ignored. +Only the first use of `macro_export` on a macro has effect. > [!NOTE] -> `rustc` currently warns on subsequent duplicate `macro_export` attributes. +> `rustc` lints against any use following the first. r[macro.decl.scope.macro_export.path-based] By default, macros only have [textually-based scoping](#textual-scope). When the `macro_export` attribute is used, the macro is reexported in the crate root, and can be referred to using a path to the macro in the crate root. From e7f0a9c03f2e909fa838911a7f5a3ebd3f8f2fc0 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 20 Oct 2025 04:25:00 +0000 Subject: [PATCH 10/10] Revise `macro_export` text In addition to some editorial clean-ups, let's add an example demonstrating the difference between textual-only scope and path-based resolution, and let's move some verbiage about intended use into an admonition. --- src/macros-by-example.md | 56 ++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 8411b8b18d..33844e18c8 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -373,12 +373,13 @@ r[macro.decl.scope.macro_export] ### The `macro_export` attribute r[macro.decl.scope.macro_export.intro] -The *`macro_export` [attribute][attributes]* marks a macro to be publicly exported from the crate, and makes it available in the root of the crate for path-based resolution. +The *`macro_export` [attribute][attributes]* exports the macro from the crate and makes it available in the root of the crate for path-based resolution. > [!EXAMPLE] > ```rust > self::m!(); -> m!(); // OK: Path-based lookup finds m in the current module. +> // ^^^^ OK: Path-based lookup finds `m` in the current module. +> m!(); // As above. > > mod inner { > super::m!(); @@ -394,7 +395,7 @@ The *`macro_export` [attribute][attributes]* marks a macro to be publicly export > ``` r[macro.decl.scope.macro_export.syntax] -The `macro_export` attribute uses the [MetaWord] syntax, or the [MetaListIdents] syntax with a single value of [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros]. +The `macro_export` attribute uses the [MetaWord] and [MetaListIdents] syntaxes. With the [MetaListIdents] syntax, it accepts a single [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros] value. r[macro.decl.scope.macro_export.allowed-positions] The `macro_export` attribute may be applied to `macro_rules` definitions. @@ -409,20 +410,47 @@ Only the first use of `macro_export` on a macro has effect. > `rustc` lints against any use following the first. r[macro.decl.scope.macro_export.path-based] -By default, macros only have [textually-based scoping](#textual-scope). When the `macro_export` attribute is used, the macro is reexported in the crate root, and can be referred to using a path to the macro in the crate root. +By default, macros only have [textual scope][macro.decl.scope.textual] and cannot be resolved by path. When the `macro_export` attribute is used, the macro is made available in the crate root and can be referred to by its path. + +> [!EXAMPLE] +> Without `macro_export`, macros only have textual scope, so path-based resolution of the macro fails. +> +> ```rust,compile_fail,E0433 +> macro_rules! m { +> () => {}; +> } +> self::m!(); // ERROR +> crate::m!(); // ERROR +> # fn main() {} +> ``` +> +> With `macro_export`, path-based resolution works. +> +> ```rust +> #[macro_export] +> macro_rules! m { +> () => {}; +> } +> self::m!(); // OK +> crate::m!(); // OK +> # fn main() {} +> ``` r[macro.decl.scope.macro_export.export] -The `macro_export` attribute causes a macro to be publicly exported from the crate root so that it can be referred to by other crates using a path. +The `macro_export` attribute causes a macro to be exported from the crate root so that it can be referred to in other crates by path. > [!EXAMPLE] -> Given the following defined in a crate named `log`: +> Given the following in a `log` crate: +> > ```rust > #[macro_export] > macro_rules! warn { > ($message:expr) => { eprintln!("WARN: {}", $message) }; > } > ``` -> Then you can refer to the macro via a path to the crate: +> +> From another crate, you can refer to the macro by path: +> > > ```rust,ignore > fn main() { @@ -431,17 +459,20 @@ The `macro_export` attribute causes a macro to be publicly exported from the cra > ``` r[macro.decl.scope.macro_export.macro_use] -`macro_export` also allows the use of [`macro_use`][macro.decl.scope.macro_use] on an `extern crate` to import the macro into the [`macro_use` prelude]. +`macro_export` allows the use of [`macro_use`][macro.decl.scope.macro_use] on an `extern crate` to import the macro into the [`macro_use` prelude]. > [!EXAMPLE] -> Given the following defined in a crate named `log`: +> Given the following in a `log` crate: +> > ```rust > #[macro_export] > macro_rules! warn { > ($message:expr) => { eprintln!("WARN: {}", $message) }; > } > ``` -> Using `macro_use` in a dependent crate means the macro can be used from the prelude: +> +> Using `macro_use` in a dependent crate allows you to use the macro from the prelude: +> > > ```rust,ignore > #[macro_use] @@ -456,7 +487,10 @@ r[macro.decl.scope.macro_export.macro_use] > ``` r[macro.decl.scope.macro_export.local_inner_macros] -Adding `local_inner_macros` to the `macro_export` attribute also causes all single-segment macro invocations in the macro definition to have an implicit `$crate::` prefix. This is intended primarily as a tool to migrate code written before [`$crate`] was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code. +Adding `local_inner_macros` to the `macro_export` attribute causes all single-segment macro invocations in the macro definition to have an implicit `$crate::` prefix. + +> [!NOTE] +> This is intended primarily as a tool to migrate code written before [`$crate`] was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code. > [!EXAMPLE] > ```rust