Skip to content

Commit 4442240

Browse files
committedJul 29, 2018
resolve: Modularize crate-local #[macro_export] macro_rules
1 parent 75af9df commit 4442240

14 files changed

+415
-32
lines changed
 

‎src/librustc_resolve/build_reduced_graph.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,20 @@ impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
5959
impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
6060
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
6161
arenas.alloc_name_binding(NameBinding {
62-
kind: NameBindingKind::Def(self.0),
62+
kind: NameBindingKind::Def(self.0, false),
63+
vis: self.1,
64+
span: self.2,
65+
expansion: self.3,
66+
})
67+
}
68+
}
69+
70+
pub(crate) struct IsMacroExport;
71+
72+
impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark, IsMacroExport) {
73+
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
74+
arenas.alloc_name_binding(NameBinding {
75+
kind: NameBindingKind::Def(self.0, true),
6376
vis: self.1,
6477
span: self.2,
6578
expansion: self.3,
@@ -772,6 +785,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
772785
fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
773786
let mark = id.placeholder_to_mark();
774787
self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark);
788+
self.resolver.unresolved_invocations_macro_export.insert(mark);
775789
let invocation = self.resolver.invocations[&mark];
776790
invocation.module.set(self.resolver.current_module);
777791
invocation.legacy_scope.set(self.legacy_scope);

‎src/librustc_resolve/lib.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
11171117

11181118
#[derive(Clone, Debug)]
11191119
enum NameBindingKind<'a> {
1120-
Def(Def),
1120+
Def(Def, /* is_macro_export */ bool),
11211121
Module(Module<'a>),
11221122
Import {
11231123
binding: &'a NameBinding<'a>,
@@ -1161,7 +1161,7 @@ impl<'a> NameBinding<'a> {
11611161

11621162
fn def(&self) -> Def {
11631163
match self.kind {
1164-
NameBindingKind::Def(def) => def,
1164+
NameBindingKind::Def(def, _) => def,
11651165
NameBindingKind::Module(module) => module.def().unwrap(),
11661166
NameBindingKind::Import { binding, .. } => binding.def(),
11671167
NameBindingKind::Ambiguity { .. } => Def::Err,
@@ -1191,8 +1191,8 @@ impl<'a> NameBinding<'a> {
11911191

11921192
fn is_variant(&self) -> bool {
11931193
match self.kind {
1194-
NameBindingKind::Def(Def::Variant(..)) |
1195-
NameBindingKind::Def(Def::VariantCtor(..)) => true,
1194+
NameBindingKind::Def(Def::Variant(..), _) |
1195+
NameBindingKind::Def(Def::VariantCtor(..), _) => true,
11961196
_ => false,
11971197
}
11981198
}
@@ -1241,7 +1241,7 @@ impl<'a> NameBinding<'a> {
12411241

12421242
fn is_macro_def(&self) -> bool {
12431243
match self.kind {
1244-
NameBindingKind::Def(Def::Macro(..)) => true,
1244+
NameBindingKind::Def(Def::Macro(..), _) => true,
12451245
_ => false,
12461246
}
12471247
}
@@ -1397,7 +1397,7 @@ pub struct Resolver<'a> {
13971397
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
13981398
macro_defs: FxHashMap<Mark, DefId>,
13991399
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
1400-
macro_exports: Vec<Export>,
1400+
macro_exports: Vec<Export>, // FIXME: Remove when `use_extern_macros` is stabilized
14011401
pub whitelisted_legacy_custom_derives: Vec<Name>,
14021402
pub found_unresolved_macro: bool,
14031403

@@ -1427,6 +1427,9 @@ pub struct Resolver<'a> {
14271427

14281428
/// Only supposed to be used by rustdoc, otherwise should be false.
14291429
pub ignore_extern_prelude_feature: bool,
1430+
1431+
/// Macro invocations in the whole crate that can expand into a `#[macro_export] macro_rules`.
1432+
unresolved_invocations_macro_export: FxHashSet<Mark>,
14301433
}
14311434

14321435
/// Nothing really interesting here, it just provides memory for the rest of the crate.
@@ -1701,7 +1704,7 @@ impl<'a> Resolver<'a> {
17011704

17021705
arenas,
17031706
dummy_binding: arenas.alloc_name_binding(NameBinding {
1704-
kind: NameBindingKind::Def(Def::Err),
1707+
kind: NameBindingKind::Def(Def::Err, false),
17051708
expansion: Mark::root(),
17061709
span: DUMMY_SP,
17071710
vis: ty::Visibility::Public,
@@ -1731,6 +1734,7 @@ impl<'a> Resolver<'a> {
17311734
current_type_ascription: Vec::new(),
17321735
injected_crate: None,
17331736
ignore_extern_prelude_feature: false,
1737+
unresolved_invocations_macro_export: FxHashSet(),
17341738
}
17351739
}
17361740

‎src/librustc_resolve/macros.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use {AmbiguityError, CrateLint, Resolver, ResolutionError, resolve_error};
1212
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult};
1313
use Namespace::{self, MacroNS};
14-
use build_reduced_graph::BuildReducedGraphVisitor;
14+
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
1515
use resolve_imports::ImportResolver;
1616
use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex,
1717
DefIndexAddressSpace};
@@ -193,7 +193,9 @@ impl<'a> base::Resolver for Resolver<'a> {
193193

194194
self.current_module = invocation.module.get();
195195
self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
196+
self.unresolved_invocations_macro_export.remove(&mark);
196197
self.current_module.unresolved_invocations.borrow_mut().extend(derives);
198+
self.unresolved_invocations_macro_export.extend(derives);
197199
for &derive in derives {
198200
self.invocations.insert(derive, invocation);
199201
}
@@ -215,7 +217,7 @@ impl<'a> base::Resolver for Resolver<'a> {
215217
let kind = ext.kind();
216218
self.macro_map.insert(def_id, ext);
217219
let binding = self.arenas.alloc_name_binding(NameBinding {
218-
kind: NameBindingKind::Def(Def::Macro(def_id, kind)),
220+
kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
219221
span: DUMMY_SP,
220222
vis: ty::Visibility::Invisible,
221223
expansion: Mark::root(),
@@ -711,12 +713,15 @@ impl<'a> Resolver<'a> {
711713

712714
match (legacy_resolution, resolution) {
713715
(Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => {
714-
let msg1 = format!("`{}` could refer to the macro defined here", ident);
715-
let msg2 = format!("`{}` could also refer to the macro imported here", ident);
716-
self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
717-
.span_note(legacy_binding.span, &msg1)
718-
.span_note(binding.span, &msg2)
719-
.emit();
716+
if legacy_binding.def_id != binding.def_ignoring_ambiguity().def_id() {
717+
let msg1 = format!("`{}` could refer to the macro defined here", ident);
718+
let msg2 =
719+
format!("`{}` could also refer to the macro imported here", ident);
720+
self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
721+
.span_note(legacy_binding.span, &msg1)
722+
.span_note(binding.span, &msg2)
723+
.emit();
724+
}
720725
},
721726
(None, Err(_)) => {
722727
assert!(def.is_none());
@@ -850,12 +855,19 @@ impl<'a> Resolver<'a> {
850855
let def = Def::Macro(def_id, MacroKind::Bang);
851856
self.all_macros.insert(ident.name, def);
852857
if attr::contains_name(&item.attrs, "macro_export") {
853-
self.macro_exports.push(Export {
854-
ident: ident.modern(),
855-
def: def,
856-
vis: ty::Visibility::Public,
857-
span: item.span,
858-
});
858+
if self.use_extern_macros {
859+
let module = self.graph_root;
860+
let vis = ty::Visibility::Public;
861+
self.define(module, ident, MacroNS,
862+
(def, vis, item.span, expansion, IsMacroExport));
863+
} else {
864+
self.macro_exports.push(Export {
865+
ident: ident.modern(),
866+
def: def,
867+
vis: ty::Visibility::Public,
868+
span: item.span,
869+
});
870+
}
859871
} else {
860872
self.unused_macros.insert(def_id);
861873
}

‎src/librustc_resolve/resolve_imports.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ impl<'a> Resolver<'a> {
211211
// if it cannot be shadowed by some new item/import expanded from a macro.
212212
// This happens either if there are no unexpanded macros, or expanded names cannot
213213
// shadow globs (that happens in macro namespace or with restricted shadowing).
214-
let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty();
214+
let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty() ||
215+
(ns == MacroNS && ptr::eq(module, self.graph_root) &&
216+
!self.unresolved_invocations_macro_export.is_empty());
215217
if let Some(binding) = resolution.binding {
216218
if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
217219
return check_usable(self, binding);
@@ -363,6 +365,18 @@ impl<'a> Resolver<'a> {
363365
resolution.binding = Some(binding);
364366
resolution.shadowed_glob = Some(old_binding);
365367
}
368+
} else if let (&NameBindingKind::Def(_, true), &NameBindingKind::Def(_, true)) =
369+
(&old_binding.kind, &binding.kind) {
370+
371+
this.session.buffer_lint_with_diagnostic(
372+
DUPLICATE_MACRO_EXPORTS,
373+
CRATE_NODE_ID,
374+
binding.span,
375+
&format!("a macro named `{}` has already been exported", ident),
376+
BuiltinLintDiagnostics::DuplicatedMacroExports(
377+
ident, old_binding.span, binding.span));
378+
379+
resolution.binding = Some(binding);
366380
} else {
367381
return Err(old_binding);
368382
}
@@ -766,7 +780,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
766780
match binding.kind {
767781
// Never suggest the name that has binding error
768782
// i.e. the name that cannot be previously resolved
769-
NameBindingKind::Def(Def::Err) => return None,
783+
NameBindingKind::Def(Def::Err, _) => return None,
770784
_ => Some(&i.name),
771785
}
772786
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(use_extern_macros)]
12+
#![allow(duplicate_macro_exports)]
13+
14+
#[macro_export]
15+
macro_rules! foo_modern { ($i:ident) => {} }
16+
17+
#[macro_export]
18+
macro_rules! foo_modern { () => {} }

‎src/test/run-pass/issue-38715.rs

+4
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
// except according to those terms.
1010

1111
// aux-build:issue_38715.rs
12+
// aux-build:issue_38715-modern.rs
1213

1314
// Test that `#[macro_export] macro_rules!` shadow earlier `#[macro_export] macro_rules!`
1415

1516
#[macro_use]
1617
extern crate issue_38715;
18+
#[macro_use]
19+
extern crate issue_38715_modern;
1720

1821
fn main() {
1922
foo!();
23+
foo_modern!();
2024
}

‎src/test/ui/duplicate-check-macro-exports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@
1313
pub use std::panic;
1414

1515
#[macro_export]
16-
macro_rules! panic { () => {} } //~ ERROR a macro named `panic` has already been exported
16+
macro_rules! panic { () => {} } //~ ERROR the name `panic` is defined multiple times
1717

1818
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
error: a macro named `panic` has already been exported
1+
error[E0255]: the name `panic` is defined multiple times
22
--> $DIR/duplicate-check-macro-exports.rs:16:1
33
|
4-
LL | macro_rules! panic { () => {} } //~ ERROR a macro named `panic` has already been exported
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `panic` already exported
4+
LL | pub use std::panic;
5+
| ---------- previous import of the macro `panic` here
6+
...
7+
LL | macro_rules! panic { () => {} } //~ ERROR the name `panic` is defined multiple times
8+
| ^^^^^^^^^^^^^^^^^^ `panic` redefined here
69
|
7-
note: previous macro export here
8-
--> $DIR/duplicate-check-macro-exports.rs:13:9
10+
= note: `panic` must be defined only once in the macro namespace of this module
11+
help: You can use `as` to change the binding name of the import
912
|
10-
LL | pub use std::panic;
11-
| ^^^^^^^^^^
13+
LL | pub use std::panic as other_panic;
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
1215

1316
error: aborting due to previous error
1417

18+
For more information about this error, try `rustc --explain E0255`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(decl_macro)]
12+
13+
macro_rules! define_exported { () => {
14+
#[macro_export]
15+
macro_rules! exported {
16+
() => ()
17+
}
18+
}}
19+
macro_rules! define_panic { () => {
20+
#[macro_export]
21+
macro_rules! panic {
22+
() => ()
23+
}
24+
}}
25+
macro_rules! define_include { () => {
26+
#[macro_export]
27+
macro_rules! include {
28+
() => ()
29+
}
30+
}}
31+
32+
use inner1::*;
33+
34+
mod inner1 {
35+
pub macro exported() {}
36+
}
37+
38+
exported!(); //~ ERROR `exported` is ambiguous
39+
40+
mod inner2 {
41+
define_exported!();
42+
}
43+
44+
fn main() {
45+
panic!(); //~ ERROR `panic` is ambiguous
46+
//~^ ERROR `panic` is ambiguous
47+
}
48+
49+
mod inner3 {
50+
define_panic!();
51+
}
52+
53+
mod inner4 {
54+
define_include!();
55+
}
56+
57+
include!(); //~ ERROR `include` is ambiguous
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
error[E0659]: `exported` is ambiguous
2+
--> $DIR/local-modularized-tricky-fail-1.rs:38:1
3+
|
4+
LL | exported!(); //~ ERROR `exported` is ambiguous
5+
| ^^^^^^^^
6+
|
7+
note: `exported` could refer to the name defined here
8+
--> $DIR/local-modularized-tricky-fail-1.rs:15:5
9+
|
10+
LL | / macro_rules! exported {
11+
LL | | () => ()
12+
LL | | }
13+
| |_____^
14+
...
15+
LL | define_exported!();
16+
| ------------------- in this macro invocation
17+
note: `exported` could also refer to the name imported here
18+
--> $DIR/local-modularized-tricky-fail-1.rs:32:5
19+
|
20+
LL | use inner1::*;
21+
| ^^^^^^^^^
22+
= note: macro-expanded macros do not shadow
23+
24+
error[E0659]: `include` is ambiguous
25+
--> $DIR/local-modularized-tricky-fail-1.rs:57:1
26+
|
27+
LL | include!(); //~ ERROR `include` is ambiguous
28+
| ^^^^^^^
29+
|
30+
note: `include` could refer to the name defined here
31+
--> $DIR/local-modularized-tricky-fail-1.rs:27:5
32+
|
33+
LL | / macro_rules! include {
34+
LL | | () => ()
35+
LL | | }
36+
| |_____^
37+
...
38+
LL | define_include!();
39+
| ------------------ in this macro invocation
40+
= note: `include` is also a builtin macro
41+
= note: macro-expanded macros do not shadow
42+
43+
error[E0659]: `panic` is ambiguous
44+
--> $DIR/local-modularized-tricky-fail-1.rs:45:5
45+
|
46+
LL | panic!(); //~ ERROR `panic` is ambiguous
47+
| ^^^^^
48+
|
49+
note: `panic` could refer to the name defined here
50+
--> $DIR/local-modularized-tricky-fail-1.rs:21:5
51+
|
52+
LL | / macro_rules! panic {
53+
LL | | () => ()
54+
LL | | }
55+
| |_____^
56+
...
57+
LL | define_panic!();
58+
| ---------------- in this macro invocation
59+
= note: `panic` is also a builtin macro
60+
= note: macro-expanded macros do not shadow
61+
62+
error[E0659]: `panic` is ambiguous
63+
--> $DIR/local-modularized-tricky-fail-1.rs:45:5
64+
|
65+
LL | panic!(); //~ ERROR `panic` is ambiguous
66+
| ^^^^^^^^^
67+
|
68+
note: `panic` could refer to the name defined here
69+
--> $DIR/local-modularized-tricky-fail-1.rs:21:5
70+
|
71+
LL | / macro_rules! panic {
72+
LL | | () => ()
73+
LL | | }
74+
| |_____^
75+
...
76+
LL | define_panic!();
77+
| ---------------- in this macro invocation
78+
= note: `panic` is also a builtin macro
79+
= note: macro-expanded macros do not shadow
80+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
81+
82+
error: aborting due to 4 previous errors
83+
84+
For more information about this error, try `rustc --explain E0659`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// `#[macro_export] macro_rules` that doen't originate from macro expansions can be placed
12+
// into the root module soon enough to act as usual items and shadow globs and preludes.
13+
14+
#![feature(decl_macro)]
15+
16+
// `macro_export` shadows globs
17+
use inner1::*;
18+
19+
mod inner1 {
20+
pub macro exported() {}
21+
}
22+
23+
exported!();
24+
25+
mod deep {
26+
fn deep() {
27+
type Deeper = [u8; {
28+
#[macro_export]
29+
macro_rules! exported {
30+
() => ( struct Б; ) //~ ERROR non-ascii idents are not fully supported
31+
}
32+
33+
0
34+
}];
35+
}
36+
}
37+
38+
// `macro_export` shadows std prelude
39+
fn main() {
40+
panic!();
41+
}
42+
43+
mod inner3 {
44+
#[macro_export]
45+
macro_rules! panic {
46+
() => ( struct Г; ) //~ ERROR non-ascii idents are not fully supported
47+
}
48+
}
49+
50+
// `macro_export` shadows builtin macros
51+
include!();
52+
53+
mod inner4 {
54+
#[macro_export]
55+
macro_rules! include {
56+
() => ( struct Д; ) //~ ERROR non-ascii idents are not fully supported
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
2+
--> $DIR/local-modularized-tricky-fail-2.rs:30:32
3+
|
4+
LL | exported!();
5+
| ------------ in this macro invocation
6+
...
7+
LL | () => ( struct Б; ) //~ ERROR non-ascii idents are not fully supported
8+
| ^
9+
|
10+
= help: add #![feature(non_ascii_idents)] to the crate attributes to enable
11+
12+
error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
13+
--> $DIR/local-modularized-tricky-fail-2.rs:46:24
14+
|
15+
LL | panic!();
16+
| --------- in this macro invocation
17+
...
18+
LL | () => ( struct Г; ) //~ ERROR non-ascii idents are not fully supported
19+
| ^
20+
|
21+
= help: add #![feature(non_ascii_idents)] to the crate attributes to enable
22+
23+
error[E0658]: non-ascii idents are not fully supported. (see issue #28979)
24+
--> $DIR/local-modularized-tricky-fail-2.rs:56:24
25+
|
26+
LL | include!();
27+
| ----------- in this macro invocation
28+
...
29+
LL | () => ( struct Д; ) //~ ERROR non-ascii idents are not fully supported
30+
| ^
31+
|
32+
= help: add #![feature(non_ascii_idents)] to the crate attributes to enable
33+
34+
error: aborting due to 3 previous errors
35+
36+
For more information about this error, try `rustc --explain E0658`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-pass
12+
13+
#![feature(use_extern_macros)]
14+
15+
macro_rules! define_exported { () => {
16+
#[macro_export]
17+
macro_rules! exported {
18+
() => ()
19+
}
20+
}}
21+
22+
mod inner1 {
23+
use super::*;
24+
exported!();
25+
}
26+
27+
mod inner2 {
28+
define_exported!();
29+
}
30+
31+
fn main() {}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-pass
12+
13+
#![feature(use_extern_macros)]
14+
15+
#[macro_export(local_inner_macros)]
16+
macro_rules! dollar_crate_exported {
17+
(1) => { $crate::exported!(); };
18+
(2) => { exported!(); };
19+
}
20+
21+
// Before `exported` is defined
22+
exported!();
23+
24+
mod inner {
25+
26+
::exported!();
27+
crate::exported!();
28+
dollar_crate_exported!(1);
29+
dollar_crate_exported!(2);
30+
31+
mod inner_inner {
32+
#[macro_export]
33+
macro_rules! exported {
34+
() => ()
35+
}
36+
}
37+
38+
// After `exported` is defined
39+
::exported!();
40+
crate::exported!();
41+
dollar_crate_exported!(1);
42+
dollar_crate_exported!(2);
43+
}
44+
45+
exported!();
46+
47+
fn main() {}

0 commit comments

Comments
 (0)
Please sign in to comment.