From 0fddc2f780b7d075797364386a77b5f2f3bf909b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 21 Oct 2020 00:46:29 +0300 Subject: [PATCH 1/2] Support `pub` on `macro_rules` --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_feature/src/active.rs | 3 ++ compiler/rustc_parse/src/parser/item.rs | 10 +--- .../rustc_resolve/src/build_reduced_graph.rs | 9 +++- compiler/rustc_span/src/symbol.rs | 1 + src/test/ui/did_you_mean/pub-macro-rules.rs | 16 ------- .../ui/did_you_mean/pub-macro-rules.stderr | 8 ---- .../feature-gate-pub_macro_rules.rs | 10 ++++ .../feature-gate-pub_macro_rules.stderr | 39 +++++++++++++++ .../macro-export-on-modularized-macros.rs | 11 +++++ .../macro-export-on-modularized-macros.stderr | 14 ++++++ src/test/ui/macros/pub-macro-rules-fail.rs | 28 +++++++++++ .../ui/macros/pub-macro-rules-fail.stderr | 48 +++++++++++++++++++ src/test/ui/macros/pub-macro-rules.rs | 20 ++++++++ 14 files changed, 183 insertions(+), 35 deletions(-) delete mode 100644 src/test/ui/did_you_mean/pub-macro-rules.rs delete mode 100644 src/test/ui/did_you_mean/pub-macro-rules.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-pub_macro_rules.rs create mode 100644 src/test/ui/feature-gates/feature-gate-pub_macro_rules.stderr create mode 100644 src/test/ui/macros/macro-export-on-modularized-macros.rs create mode 100644 src/test/ui/macros/macro-export-on-modularized-macros.stderr create mode 100644 src/test/ui/macros/pub-macro-rules-fail.rs create mode 100644 src/test/ui/macros/pub-macro-rules-fail.stderr create mode 100644 src/test/ui/macros/pub-macro-rules.rs diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 6514de2b81315..474ec2b589b71 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -665,6 +665,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { // involved, so we only emit errors where there are no other parsing errors. gate_all!(destructuring_assignment, "destructuring assignments are unstable"); } + gate_all!(pub_macro_rules, "`pub` on `macro_rules` items is unstable"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 2d0009c225c59..56f5c3b79bef9 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -638,6 +638,9 @@ declare_features! ( /// Allows macro attributes to observe output of `#[derive]`. (active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None), + /// Allows `pub` on `macro_rules` items. + (active, pub_macro_rules, "1.49.0", Some(78855), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index cdea82f50ede4..45f6dbca9f048 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1488,15 +1488,7 @@ impl<'a> Parser<'a> { let vstr = pprust::vis_to_string(vis); let vstr = vstr.trim_end(); if macro_rules { - let msg = format!("can't qualify macro_rules invocation with `{}`", vstr); - self.struct_span_err(vis.span, &msg) - .span_suggestion( - vis.span, - "try exporting the macro", - "#[macro_export]".to_owned(), - Applicability::MaybeIncorrect, // speculative - ) - .emit(); + self.sess.gated_spans.gate(sym::pub_macro_rules, vis.span); } else { self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`") .span_suggestion( diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 79ed0b5308dab..65e5b0dddea30 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1230,13 +1230,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }; let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id()); + let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export); self.r.macro_map.insert(def_id.to_def_id(), ext); self.r.local_macro_def_scopes.insert(def_id, parent_scope.module); - if macro_rules { + if macro_rules && matches!(item.vis.kind, ast::VisibilityKind::Inherited) { let ident = ident.normalize_to_macros_2_0(); self.r.macro_names.insert(ident); - let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export); let vis = if is_macro_export { ty::Visibility::Public } else { @@ -1261,6 +1261,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }), )) } else { + if is_macro_export { + let what = if macro_rules { "`macro_rules` with `pub`" } else { "`macro` items" }; + let msg = format!("`#[macro_export]` cannot be used on {what}"); + self.r.session.span_err(item.span, &msg); + } let module = parent_scope.module; let vis = match item.kind { // Visibilities must not be resolved non-speculatively twice diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 653d70b6cf244..d4a0f968eee1e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -874,6 +874,7 @@ symbols! { ptr_guaranteed_eq, ptr_guaranteed_ne, ptr_offset_from, + pub_macro_rules, pub_restricted, pure, pushpop_unsafe, diff --git a/src/test/ui/did_you_mean/pub-macro-rules.rs b/src/test/ui/did_you_mean/pub-macro-rules.rs deleted file mode 100644 index c5393703f7091..0000000000000 --- a/src/test/ui/did_you_mean/pub-macro-rules.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[macro_use] mod bleh { - pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation - ($n:ident) => ( - fn $n () -> i32 { - 1 - } - ) - } - -} - -foo!(meh); - -fn main() { - println!("{}", meh()); -} diff --git a/src/test/ui/did_you_mean/pub-macro-rules.stderr b/src/test/ui/did_you_mean/pub-macro-rules.stderr deleted file mode 100644 index 0bde5783b8cc6..0000000000000 --- a/src/test/ui/did_you_mean/pub-macro-rules.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: can't qualify macro_rules invocation with `pub` - --> $DIR/pub-macro-rules.rs:2:5 - | -LL | pub macro_rules! foo { - | ^^^ help: try exporting the macro: `#[macro_export]` - -error: aborting due to previous error - diff --git a/src/test/ui/feature-gates/feature-gate-pub_macro_rules.rs b/src/test/ui/feature-gates/feature-gate-pub_macro_rules.rs new file mode 100644 index 0000000000000..5504ec317ae59 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-pub_macro_rules.rs @@ -0,0 +1,10 @@ +pub macro_rules! m1 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable + +#[cfg(FALSE)] +pub macro_rules! m2 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable + +pub(crate) macro_rules! m3 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable + +pub(in self) macro_rules! m4 { () => {} } //~ ERROR `pub` on `macro_rules` items is unstable + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-pub_macro_rules.stderr b/src/test/ui/feature-gates/feature-gate-pub_macro_rules.stderr new file mode 100644 index 0000000000000..bfaec398d9a97 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-pub_macro_rules.stderr @@ -0,0 +1,39 @@ +error[E0658]: `pub` on `macro_rules` items is unstable + --> $DIR/feature-gate-pub_macro_rules.rs:1:1 + | +LL | pub macro_rules! m1 { () => {} } + | ^^^ + | + = note: see issue #78855 for more information + = help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable + +error[E0658]: `pub` on `macro_rules` items is unstable + --> $DIR/feature-gate-pub_macro_rules.rs:4:1 + | +LL | pub macro_rules! m2 { () => {} } + | ^^^ + | + = note: see issue #78855 for more information + = help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable + +error[E0658]: `pub` on `macro_rules` items is unstable + --> $DIR/feature-gate-pub_macro_rules.rs:6:1 + | +LL | pub(crate) macro_rules! m3 { () => {} } + | ^^^^^^^^^^ + | + = note: see issue #78855 for more information + = help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable + +error[E0658]: `pub` on `macro_rules` items is unstable + --> $DIR/feature-gate-pub_macro_rules.rs:8:1 + | +LL | pub(in self) macro_rules! m4 { () => {} } + | ^^^^^^^^^^^^ + | + = note: see issue #78855 for more information + = help: add `#![feature(pub_macro_rules)]` to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/macros/macro-export-on-modularized-macros.rs b/src/test/ui/macros/macro-export-on-modularized-macros.rs new file mode 100644 index 0000000000000..467c6ba7b78e4 --- /dev/null +++ b/src/test/ui/macros/macro-export-on-modularized-macros.rs @@ -0,0 +1,11 @@ +#![feature(decl_macro)] +#![feature(pub_macro_rules)] + +#[macro_export] +macro m1() {} //~ ERROR `#[macro_export]` cannot be used on `macro` items + +#[macro_export] +pub macro_rules! m2 { () => {} } +//~^ ERROR `#[macro_export]` cannot be used on `macro_rules` with `pub` + +fn main() {} diff --git a/src/test/ui/macros/macro-export-on-modularized-macros.stderr b/src/test/ui/macros/macro-export-on-modularized-macros.stderr new file mode 100644 index 0000000000000..8bb031e12cba2 --- /dev/null +++ b/src/test/ui/macros/macro-export-on-modularized-macros.stderr @@ -0,0 +1,14 @@ +error: `#[macro_export]` cannot be used on `macro` items + --> $DIR/macro-export-on-modularized-macros.rs:5:1 + | +LL | macro m1() {} + | ^^^^^^^^^^^^^ + +error: `#[macro_export]` cannot be used on `macro_rules` with `pub` + --> $DIR/macro-export-on-modularized-macros.rs:8:1 + | +LL | pub macro_rules! m2 { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/macros/pub-macro-rules-fail.rs b/src/test/ui/macros/pub-macro-rules-fail.rs new file mode 100644 index 0000000000000..bdb4c73f18b18 --- /dev/null +++ b/src/test/ui/macros/pub-macro-rules-fail.rs @@ -0,0 +1,28 @@ +#![feature(pub_macro_rules)] + +#[macro_use] +mod m { + pub macro_rules! mac { () => {} } + + // `pub` `macro_rules` cannot be redefined in the same module. + pub macro_rules! mac { () => {} } //~ ERROR the name `mac` is defined multiple times + + pub(self) macro_rules! private_mac { () => {} } +} + +const _: () = { + pub macro_rules! block_mac { () => {} } +}; + +mod n { + // Scope of `pub` `macro_rules` is not extended by `#[macro_use]`. + mac!(); //~ ERROR cannot find macro `mac` in this scope + + // `pub` `macro_rules` doesn't put the macro into the root module, unlike `#[macro_export]`. + crate::mac!(); //~ ERROR failed to resolve: maybe a missing crate `mac` + crate::block_mac!(); //~ ERROR failed to resolve: maybe a missing crate `block_mac` + + crate::m::private_mac!(); //~ ERROR macro `private_mac` is private +} + +fn main() {} diff --git a/src/test/ui/macros/pub-macro-rules-fail.stderr b/src/test/ui/macros/pub-macro-rules-fail.stderr new file mode 100644 index 0000000000000..588d79dd76a4b --- /dev/null +++ b/src/test/ui/macros/pub-macro-rules-fail.stderr @@ -0,0 +1,48 @@ +error[E0428]: the name `mac` is defined multiple times + --> $DIR/pub-macro-rules-fail.rs:8:5 + | +LL | pub macro_rules! mac { () => {} } + | -------------------- previous definition of the macro `mac` here +... +LL | pub macro_rules! mac { () => {} } + | ^^^^^^^^^^^^^^^^^^^^ `mac` redefined here + | + = note: `mac` must be defined only once in the macro namespace of this module + +error[E0433]: failed to resolve: maybe a missing crate `mac`? + --> $DIR/pub-macro-rules-fail.rs:22:12 + | +LL | crate::mac!(); + | ^^^ maybe a missing crate `mac`? + +error[E0433]: failed to resolve: maybe a missing crate `block_mac`? + --> $DIR/pub-macro-rules-fail.rs:23:12 + | +LL | crate::block_mac!(); + | ^^^^^^^^^ maybe a missing crate `block_mac`? + +error: cannot find macro `mac` in this scope + --> $DIR/pub-macro-rules-fail.rs:19:5 + | +LL | mac!(); + | ^^^ + | + = note: consider importing this macro: + m::mac + +error[E0603]: macro `private_mac` is private + --> $DIR/pub-macro-rules-fail.rs:25:15 + | +LL | crate::m::private_mac!(); + | ^^^^^^^^^^^ private macro + | +note: the macro `private_mac` is defined here + --> $DIR/pub-macro-rules-fail.rs:10:5 + | +LL | pub(self) macro_rules! private_mac { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0428, E0433, E0603. +For more information about an error, try `rustc --explain E0428`. diff --git a/src/test/ui/macros/pub-macro-rules.rs b/src/test/ui/macros/pub-macro-rules.rs new file mode 100644 index 0000000000000..cd4a845f7c07d --- /dev/null +++ b/src/test/ui/macros/pub-macro-rules.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(pub_macro_rules)] + +mod m { + // `pub` `macro_rules` can be used earlier in item order than they are defined. + foo!(); + + pub macro_rules! foo { () => {} } + + // `pub(...)` works too. + pub(super) macro_rules! bar { () => {} } +} + +// `pub` `macro_rules` are available by module path. +m::foo!(); + +m::bar!(); + +fn main() {} From b3000ec0cdb35b305bfe954db4b14ce32cbc255b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 19 Feb 2021 12:47:53 -0300 Subject: [PATCH 2/2] Update pub_macro_rules since version --- compiler/rustc_feature/src/active.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 56f5c3b79bef9..3f484ab568652 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -639,7 +639,7 @@ declare_features! ( (active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None), /// Allows `pub` on `macro_rules` items. - (active, pub_macro_rules, "1.49.0", Some(78855), None), + (active, pub_macro_rules, "1.52.0", Some(78855), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates