From e1ce3672643440113ff5b7190f0e1c2a37e4a7cd Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Mon, 15 Dec 2025 11:38:24 -0800 Subject: [PATCH 1/2] Test current macro_rules re-export behavior --- tests/ui/macros/auxiliary/implicit-pub.rs | 16 ++++++++++++++++ .../macros/implicit-pub-macros2-linted-still.rs | 10 ++++++++++ .../implicit-pub-macros2-linted-still.stderr | 17 +++++++++++++++++ .../ui/macros/implicit-pub-still-unreachable.rs | 8 ++++++++ .../implicit-pub-still-unreachable.stderr | 9 +++++++++ .../ui/macros/implicit-pub-unreachable-lint.rs | 12 ++++++++++++ .../macros/implicit-pub-unreachable-lint.stderr | 17 +++++++++++++++++ .../macros/implicit-pub-unreachable-no-lint.rs | 7 +++++++ tests/ui/macros/implicit-pub.rs | 10 ++++++++++ 9 files changed, 106 insertions(+) create mode 100644 tests/ui/macros/auxiliary/implicit-pub.rs create mode 100644 tests/ui/macros/implicit-pub-macros2-linted-still.rs create mode 100644 tests/ui/macros/implicit-pub-macros2-linted-still.stderr create mode 100644 tests/ui/macros/implicit-pub-still-unreachable.rs create mode 100644 tests/ui/macros/implicit-pub-still-unreachable.stderr create mode 100644 tests/ui/macros/implicit-pub-unreachable-lint.rs create mode 100644 tests/ui/macros/implicit-pub-unreachable-lint.stderr create mode 100644 tests/ui/macros/implicit-pub-unreachable-no-lint.rs create mode 100644 tests/ui/macros/implicit-pub.rs diff --git a/tests/ui/macros/auxiliary/implicit-pub.rs b/tests/ui/macros/auxiliary/implicit-pub.rs new file mode 100644 index 0000000000000..44526dccab742 --- /dev/null +++ b/tests/ui/macros/auxiliary/implicit-pub.rs @@ -0,0 +1,16 @@ +//@ edition:2018 +#[allow(unused_macros)] +macro_rules! fake_pub { + () => {} +} + +#[macro_export] +macro_rules! real_pub { + () => {} +} + +pub mod inner { + pub use real_pub; +} + +pub use real_pub as real_pub_reexport; diff --git a/tests/ui/macros/implicit-pub-macros2-linted-still.rs b/tests/ui/macros/implicit-pub-macros2-linted-still.rs new file mode 100644 index 0000000000000..6ddbf9993df60 --- /dev/null +++ b/tests/ui/macros/implicit-pub-macros2-linted-still.rs @@ -0,0 +1,10 @@ +//@ edition:2018 +#![feature(decl_macro)] +#![crate_type = "lib"] +#![deny(unreachable_pub)] + +mod inner { + pub macro m($inner_str:expr) { //~ ERROR: unreachable `pub` item [unreachable_pub] + struct S; + } +} diff --git a/tests/ui/macros/implicit-pub-macros2-linted-still.stderr b/tests/ui/macros/implicit-pub-macros2-linted-still.stderr new file mode 100644 index 0000000000000..9549a88eabf4e --- /dev/null +++ b/tests/ui/macros/implicit-pub-macros2-linted-still.stderr @@ -0,0 +1,17 @@ +error: unreachable `pub` item + --> $DIR/implicit-pub-macros2-linted-still.rs:7:5 + | +LL | pub macro m($inner_str:expr) { + | ---^^^^^^^^ + | | + | help: consider restricting its visibility: `pub(crate)` + | + = help: or consider exporting it for use by other crates +note: the lint level is defined here + --> $DIR/implicit-pub-macros2-linted-still.rs:4:9 + | +LL | #![deny(unreachable_pub)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/macros/implicit-pub-still-unreachable.rs b/tests/ui/macros/implicit-pub-still-unreachable.rs new file mode 100644 index 0000000000000..9eca316682d5a --- /dev/null +++ b/tests/ui/macros/implicit-pub-still-unreachable.rs @@ -0,0 +1,8 @@ +//@ aux-build:implicit-pub.rs +//@ edition:2018 + +extern crate implicit_pub; + +fn main() { + implicit_pub::inner::fake_pub!(); //~ error: failed to resolve: could not find `fake_pub` in `inner` [E0433] +} diff --git a/tests/ui/macros/implicit-pub-still-unreachable.stderr b/tests/ui/macros/implicit-pub-still-unreachable.stderr new file mode 100644 index 0000000000000..468ab4316946c --- /dev/null +++ b/tests/ui/macros/implicit-pub-still-unreachable.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: could not find `fake_pub` in `inner` + --> $DIR/implicit-pub-still-unreachable.rs:7:26 + | +LL | implicit_pub::inner::fake_pub!(); + | ^^^^^^^^ could not find `fake_pub` in `inner` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/macros/implicit-pub-unreachable-lint.rs b/tests/ui/macros/implicit-pub-unreachable-lint.rs new file mode 100644 index 0000000000000..d4fff9729b951 --- /dev/null +++ b/tests/ui/macros/implicit-pub-unreachable-lint.rs @@ -0,0 +1,12 @@ +//@ edition:2018 +#![crate_type = "lib"] +#![deny(unreachable_pub)] + +#[macro_export] +macro_rules! not_reexported { + () => {} +} + +mod inner { + pub use not_reexported; //~ ERROR: unreachable `pub` item [unreachable_pub] +} diff --git a/tests/ui/macros/implicit-pub-unreachable-lint.stderr b/tests/ui/macros/implicit-pub-unreachable-lint.stderr new file mode 100644 index 0000000000000..fc513a7d4ac23 --- /dev/null +++ b/tests/ui/macros/implicit-pub-unreachable-lint.stderr @@ -0,0 +1,17 @@ +error: unreachable `pub` item + --> $DIR/implicit-pub-unreachable-lint.rs:11:13 + | +LL | pub use not_reexported; + | --- ^^^^^^^^^^^^^^ + | | + | help: consider restricting its visibility: `pub(crate)` + | + = help: or consider exporting it for use by other crates +note: the lint level is defined here + --> $DIR/implicit-pub-unreachable-lint.rs:3:9 + | +LL | #![deny(unreachable_pub)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/macros/implicit-pub-unreachable-no-lint.rs b/tests/ui/macros/implicit-pub-unreachable-no-lint.rs new file mode 100644 index 0000000000000..5f26bd9965f73 --- /dev/null +++ b/tests/ui/macros/implicit-pub-unreachable-no-lint.rs @@ -0,0 +1,7 @@ +//@ check-pass +//@ edition:2018 +#![crate_type = "lib"] + +macro_rules! not_reexported { + () => {} +} diff --git a/tests/ui/macros/implicit-pub.rs b/tests/ui/macros/implicit-pub.rs new file mode 100644 index 0000000000000..3f0025e92b753 --- /dev/null +++ b/tests/ui/macros/implicit-pub.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ aux-build:implicit-pub.rs +//@ edition:2018 + +extern crate implicit_pub; + +fn main() { + implicit_pub::inner::real_pub!(); + implicit_pub::real_pub_reexport!(); +} From 9853d9706ca085979e6129a07785522b26c8070e Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Mon, 15 Dec 2025 11:38:24 -0800 Subject: [PATCH 2/2] Add feature to set path-based visibility of macro_rules to pub by default --- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_lint/src/builtin.rs | 5 +++++ .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + .../feature-gate-macro-implicit-pub.rs | 8 +++++++ .../feature-gate-macro-implicit-pub.stderr | 21 +++++++++++++++++++ tests/ui/macros/auxiliary/implicit-pub.rs | 2 +- .../macros/implicit-pub-unreachable-lint.rs | 2 +- .../implicit-pub-unreachable-lint.stderr | 2 +- 9 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-macro-implicit-pub.rs create mode 100644 tests/ui/feature-gates/feature-gate-macro-implicit-pub.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fe053935f9e64..e263f3f99e549 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -568,6 +568,8 @@ declare_features! ( (unstable, macro_attr, "1.91.0", Some(143547)), /// Allow `macro_rules!` derive rules (unstable, macro_derive, "1.91.0", Some(143549)), + /// Make `macro_rules!` implicitly pub even without `macro_export` + (unstable, macro_implicit_pub, "CURRENT_RUSTC_VERSION", Some(148610)), /// Give access to additional metadata about declarative macro meta-variables. (unstable, macro_metavar_expr, "1.61.0", Some(83527)), /// Provides a way to concatenate identifiers using metavariable expressions. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 810760e9f53e6..b0e63616ef04c 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1288,6 +1288,11 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub { if let hir::ItemKind::Use(_, hir::UseKind::ListStem) = &item.kind { return; } + // Do not warn for macro_rules definitions which are pub and unreachable by default, + // only check their associated use re-exports. + if let hir::ItemKind::Macro(_, ast::MacroDef { macro_rules: true, .. }, _) = &item.kind { + return; + } self.perform_lint(cx, "item", item.owner_id.def_id, item.vis_span, true); } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index b9c945a440f88..9abaec6a20496 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1299,7 +1299,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let ident = ident.normalize_to_macros_2_0(); self.r.macro_names.insert(ident); let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export); - let vis = if is_macro_export { + let vis = if is_macro_export || self.r.tcx().features().macro_implicit_pub() { Visibility::Public } else { Visibility::Restricted(CRATE_DEF_ID) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8e464b55d6c23..038983566ba5d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1380,6 +1380,7 @@ symbols! { macro_derive, macro_escape, macro_export, + macro_implicit_pub, macro_lifetime_matcher, macro_literal_matcher, macro_metavar_expr, diff --git a/tests/ui/feature-gates/feature-gate-macro-implicit-pub.rs b/tests/ui/feature-gates/feature-gate-macro-implicit-pub.rs new file mode 100644 index 0000000000000..ba38e5efea895 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-macro-implicit-pub.rs @@ -0,0 +1,8 @@ +//@ edition:2018 +#![crate_type = "lib"] + +macro_rules! not_pub { + () => {} +} + +pub use not_pub; //~ ERROR: `not_pub` is only public within the crate, and cannot be re-exported outside [E0364] diff --git a/tests/ui/feature-gates/feature-gate-macro-implicit-pub.stderr b/tests/ui/feature-gates/feature-gate-macro-implicit-pub.stderr new file mode 100644 index 0000000000000..b9ce7a104c1a9 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-macro-implicit-pub.stderr @@ -0,0 +1,21 @@ +error[E0364]: `not_pub` is only public within the crate, and cannot be re-exported outside + --> $DIR/feature-gate-macro-implicit-pub.rs:8:9 + | +LL | pub use not_pub; + | ^^^^^^^ + | +help: consider adding a `#[macro_export]` to the macro in the imported module + --> $DIR/feature-gate-macro-implicit-pub.rs:4:1 + | +LL | / macro_rules! not_pub { +LL | | () => {} +LL | | } + | |_^ +help: in case you want to use the macro within this crate only, reduce the visibility to `pub(crate)` + | +LL | pub(crate) use not_pub; + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0364`. diff --git a/tests/ui/macros/auxiliary/implicit-pub.rs b/tests/ui/macros/auxiliary/implicit-pub.rs index 44526dccab742..c7ee52f42193f 100644 --- a/tests/ui/macros/auxiliary/implicit-pub.rs +++ b/tests/ui/macros/auxiliary/implicit-pub.rs @@ -1,10 +1,10 @@ //@ edition:2018 +#![feature(macro_implicit_pub)] #[allow(unused_macros)] macro_rules! fake_pub { () => {} } -#[macro_export] macro_rules! real_pub { () => {} } diff --git a/tests/ui/macros/implicit-pub-unreachable-lint.rs b/tests/ui/macros/implicit-pub-unreachable-lint.rs index d4fff9729b951..82401785b8c37 100644 --- a/tests/ui/macros/implicit-pub-unreachable-lint.rs +++ b/tests/ui/macros/implicit-pub-unreachable-lint.rs @@ -1,8 +1,8 @@ //@ edition:2018 #![crate_type = "lib"] +#![feature(macro_implicit_pub)] #![deny(unreachable_pub)] -#[macro_export] macro_rules! not_reexported { () => {} } diff --git a/tests/ui/macros/implicit-pub-unreachable-lint.stderr b/tests/ui/macros/implicit-pub-unreachable-lint.stderr index fc513a7d4ac23..9c3bfbabc25fd 100644 --- a/tests/ui/macros/implicit-pub-unreachable-lint.stderr +++ b/tests/ui/macros/implicit-pub-unreachable-lint.stderr @@ -8,7 +8,7 @@ LL | pub use not_reexported; | = help: or consider exporting it for use by other crates note: the lint level is defined here - --> $DIR/implicit-pub-unreachable-lint.rs:3:9 + --> $DIR/implicit-pub-unreachable-lint.rs:4:9 | LL | #![deny(unreachable_pub)] | ^^^^^^^^^^^^^^^