Skip to content

Commit

Permalink
Rollup merge of rust-lang#82296 - spastorino:pubrules, r=nikomatsakis
Browse files Browse the repository at this point in the history
Support `pub` on `macro_rules`

This rebases and updates `since` version of rust-lang#78166 from `@petrochenkov`

r? `@nikomatsakis`
  • Loading branch information
Dylan-DPC authored Feb 20, 2021
2 parents 7109440 + b3000ec commit 50272eb
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 35 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.52.0", Some(78855), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
10 changes: 1 addition & 9 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1475,15 +1475,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(
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ symbols! {
ptr_guaranteed_eq,
ptr_guaranteed_ne,
ptr_offset_from,
pub_macro_rules,
pub_restricted,
pure,
pushpop_unsafe,
Expand Down
16 changes: 0 additions & 16 deletions src/test/ui/did_you_mean/pub-macro-rules.rs

This file was deleted.

8 changes: 0 additions & 8 deletions src/test/ui/did_you_mean/pub-macro-rules.stderr

This file was deleted.

10 changes: 10 additions & 0 deletions src/test/ui/feature-gates/feature-gate-pub_macro_rules.rs
Original file line number Diff line number Diff line change
@@ -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() {}
39 changes: 39 additions & 0 deletions src/test/ui/feature-gates/feature-gate-pub_macro_rules.stderr
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
11 changes: 11 additions & 0 deletions src/test/ui/macros/macro-export-on-modularized-macros.rs
Original file line number Diff line number Diff line change
@@ -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() {}
14 changes: 14 additions & 0 deletions src/test/ui/macros/macro-export-on-modularized-macros.stderr
Original file line number Diff line number Diff line change
@@ -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

28 changes: 28 additions & 0 deletions src/test/ui/macros/pub-macro-rules-fail.rs
Original file line number Diff line number Diff line change
@@ -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() {}
48 changes: 48 additions & 0 deletions src/test/ui/macros/pub-macro-rules-fail.stderr
Original file line number Diff line number Diff line change
@@ -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`.
20 changes: 20 additions & 0 deletions src/test/ui/macros/pub-macro-rules.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 50272eb

Please sign in to comment.