Skip to content

Commit e2561c5

Browse files
authored
Rollup merge of #82296 - spastorino:pubrules, r=nikomatsakis
Support `pub` on `macro_rules` This rebases and updates `since` version of #78166 from ``@petrochenkov`` r? ``@nikomatsakis``
2 parents 2982ba5 + b3000ec commit e2561c5

14 files changed

+183
-35
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
665665
// involved, so we only emit errors where there are no other parsing errors.
666666
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
667667
}
668+
gate_all!(pub_macro_rules, "`pub` on `macro_rules` items is unstable");
668669

669670
// All uses of `gate_all!` below this point were added in #65742,
670671
// and subsequently disabled (with the non-early gating readded).

compiler/rustc_feature/src/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ declare_features! (
638638
/// Allows macro attributes to observe output of `#[derive]`.
639639
(active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None),
640640

641+
/// Allows `pub` on `macro_rules` items.
642+
(active, pub_macro_rules, "1.52.0", Some(78855), None),
643+
641644
// -------------------------------------------------------------------------
642645
// feature-group-end: actual feature gates
643646
// -------------------------------------------------------------------------

compiler/rustc_parse/src/parser/item.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1475,15 +1475,7 @@ impl<'a> Parser<'a> {
14751475
let vstr = pprust::vis_to_string(vis);
14761476
let vstr = vstr.trim_end();
14771477
if macro_rules {
1478-
let msg = format!("can't qualify macro_rules invocation with `{}`", vstr);
1479-
self.struct_span_err(vis.span, &msg)
1480-
.span_suggestion(
1481-
vis.span,
1482-
"try exporting the macro",
1483-
"#[macro_export]".to_owned(),
1484-
Applicability::MaybeIncorrect, // speculative
1485-
)
1486-
.emit();
1478+
self.sess.gated_spans.gate(sym::pub_macro_rules, vis.span);
14871479
} else {
14881480
self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`")
14891481
.span_suggestion(

compiler/rustc_resolve/src/build_reduced_graph.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1230,13 +1230,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
12301230
};
12311231

12321232
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id());
1233+
let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export);
12331234
self.r.macro_map.insert(def_id.to_def_id(), ext);
12341235
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
12351236

1236-
if macro_rules {
1237+
if macro_rules && matches!(item.vis.kind, ast::VisibilityKind::Inherited) {
12371238
let ident = ident.normalize_to_macros_2_0();
12381239
self.r.macro_names.insert(ident);
1239-
let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export);
12401240
let vis = if is_macro_export {
12411241
ty::Visibility::Public
12421242
} else {
@@ -1261,6 +1261,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
12611261
}),
12621262
))
12631263
} else {
1264+
if is_macro_export {
1265+
let what = if macro_rules { "`macro_rules` with `pub`" } else { "`macro` items" };
1266+
let msg = format!("`#[macro_export]` cannot be used on {what}");
1267+
self.r.session.span_err(item.span, &msg);
1268+
}
12641269
let module = parent_scope.module;
12651270
let vis = match item.kind {
12661271
// Visibilities must not be resolved non-speculatively twice

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ symbols! {
881881
ptr_guaranteed_eq,
882882
ptr_guaranteed_ne,
883883
ptr_offset_from,
884+
pub_macro_rules,
884885
pub_restricted,
885886
pure,
886887
pushpop_unsafe,

src/test/ui/did_you_mean/pub-macro-rules.rs

-16
This file was deleted.

src/test/ui/did_you_mean/pub-macro-rules.stderr

-8
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pub macro_rules! m1 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable
2+
3+
#[cfg(FALSE)]
4+
pub macro_rules! m2 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable
5+
6+
pub(crate) macro_rules! m3 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable
7+
8+
pub(in self) macro_rules! m4 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0658]: `pub` on `macro_rules` items is unstable
2+
--> $DIR/feature-gate-pub_macro_rules.rs:1:1
3+
|
4+
LL | pub macro_rules! m1 { () => {} }
5+
| ^^^
6+
|
7+
= note: see issue #78855 <https://github.com/rust-lang/rust/issues/78855> for more information
8+
= help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable
9+
10+
error[E0658]: `pub` on `macro_rules` items is unstable
11+
--> $DIR/feature-gate-pub_macro_rules.rs:4:1
12+
|
13+
LL | pub macro_rules! m2 { () => {} }
14+
| ^^^
15+
|
16+
= note: see issue #78855 <https://github.com/rust-lang/rust/issues/78855> for more information
17+
= help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable
18+
19+
error[E0658]: `pub` on `macro_rules` items is unstable
20+
--> $DIR/feature-gate-pub_macro_rules.rs:6:1
21+
|
22+
LL | pub(crate) macro_rules! m3 { () => {} }
23+
| ^^^^^^^^^^
24+
|
25+
= note: see issue #78855 <https://github.com/rust-lang/rust/issues/78855> for more information
26+
= help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable
27+
28+
error[E0658]: `pub` on `macro_rules` items is unstable
29+
--> $DIR/feature-gate-pub_macro_rules.rs:8:1
30+
|
31+
LL | pub(in self) macro_rules! m4 { () => {} }
32+
| ^^^^^^^^^^^^
33+
|
34+
= note: see issue #78855 <https://github.com/rust-lang/rust/issues/78855> for more information
35+
= help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable
36+
37+
error: aborting due to 4 previous errors
38+
39+
For more information about this error, try `rustc --explain E0658`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(decl_macro)]
2+
#![feature(pub_macro_rules)]
3+
4+
#[macro_export]
5+
macro m1() {} //~ ERROR `#[macro_export]` cannot be used on `macro` items
6+
7+
#[macro_export]
8+
pub macro_rules! m2 { () => {} }
9+
//~^ ERROR `#[macro_export]` cannot be used on `macro_rules` with `pub`
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: `#[macro_export]` cannot be used on `macro` items
2+
--> $DIR/macro-export-on-modularized-macros.rs:5:1
3+
|
4+
LL | macro m1() {}
5+
| ^^^^^^^^^^^^^
6+
7+
error: `#[macro_export]` cannot be used on `macro_rules` with `pub`
8+
--> $DIR/macro-export-on-modularized-macros.rs:8:1
9+
|
10+
LL | pub macro_rules! m2 { () => {} }
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![feature(pub_macro_rules)]
2+
3+
#[macro_use]
4+
mod m {
5+
pub macro_rules! mac { () => {} }
6+
7+
// `pub` `macro_rules` cannot be redefined in the same module.
8+
pub macro_rules! mac { () => {} } //~ ERROR the name `mac` is defined multiple times
9+
10+
pub(self) macro_rules! private_mac { () => {} }
11+
}
12+
13+
const _: () = {
14+
pub macro_rules! block_mac { () => {} }
15+
};
16+
17+
mod n {
18+
// Scope of `pub` `macro_rules` is not extended by `#[macro_use]`.
19+
mac!(); //~ ERROR cannot find macro `mac` in this scope
20+
21+
// `pub` `macro_rules` doesn't put the macro into the root module, unlike `#[macro_export]`.
22+
crate::mac!(); //~ ERROR failed to resolve: maybe a missing crate `mac`
23+
crate::block_mac!(); //~ ERROR failed to resolve: maybe a missing crate `block_mac`
24+
25+
crate::m::private_mac!(); //~ ERROR macro `private_mac` is private
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error[E0428]: the name `mac` is defined multiple times
2+
--> $DIR/pub-macro-rules-fail.rs:8:5
3+
|
4+
LL | pub macro_rules! mac { () => {} }
5+
| -------------------- previous definition of the macro `mac` here
6+
...
7+
LL | pub macro_rules! mac { () => {} }
8+
| ^^^^^^^^^^^^^^^^^^^^ `mac` redefined here
9+
|
10+
= note: `mac` must be defined only once in the macro namespace of this module
11+
12+
error[E0433]: failed to resolve: maybe a missing crate `mac`?
13+
--> $DIR/pub-macro-rules-fail.rs:22:12
14+
|
15+
LL | crate::mac!();
16+
| ^^^ maybe a missing crate `mac`?
17+
18+
error[E0433]: failed to resolve: maybe a missing crate `block_mac`?
19+
--> $DIR/pub-macro-rules-fail.rs:23:12
20+
|
21+
LL | crate::block_mac!();
22+
| ^^^^^^^^^ maybe a missing crate `block_mac`?
23+
24+
error: cannot find macro `mac` in this scope
25+
--> $DIR/pub-macro-rules-fail.rs:19:5
26+
|
27+
LL | mac!();
28+
| ^^^
29+
|
30+
= note: consider importing this macro:
31+
m::mac
32+
33+
error[E0603]: macro `private_mac` is private
34+
--> $DIR/pub-macro-rules-fail.rs:25:15
35+
|
36+
LL | crate::m::private_mac!();
37+
| ^^^^^^^^^^^ private macro
38+
|
39+
note: the macro `private_mac` is defined here
40+
--> $DIR/pub-macro-rules-fail.rs:10:5
41+
|
42+
LL | pub(self) macro_rules! private_mac { () => {} }
43+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44+
45+
error: aborting due to 5 previous errors
46+
47+
Some errors have detailed explanations: E0428, E0433, E0603.
48+
For more information about an error, try `rustc --explain E0428`.

src/test/ui/macros/pub-macro-rules.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// check-pass
2+
3+
#![feature(pub_macro_rules)]
4+
5+
mod m {
6+
// `pub` `macro_rules` can be used earlier in item order than they are defined.
7+
foo!();
8+
9+
pub macro_rules! foo { () => {} }
10+
11+
// `pub(...)` works too.
12+
pub(super) macro_rules! bar { () => {} }
13+
}
14+
15+
// `pub` `macro_rules` are available by module path.
16+
m::foo!();
17+
18+
m::bar!();
19+
20+
fn main() {}

0 commit comments

Comments
 (0)