Skip to content

rustdoc: Inherit inline attributes for declarative macros#154902

Merged
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
shivendra02467:fix-rustdoc-macro-inline
Apr 8, 2026
Merged

rustdoc: Inherit inline attributes for declarative macros#154902
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
shivendra02467:fix-rustdoc-macro-inline

Conversation

@shivendra02467
Copy link
Copy Markdown
Contributor

@shivendra02467 shivendra02467 commented Apr 6, 2026

When explicitly re-exporting a declarative macro by name, rustdoc previously bypassed intermediate re-exports and dropped #[doc(inline)] attributes, causing the macro to be incorrectly stripped if the original definition was #[doc(hidden)].

This updates generate_item_with_correct_attrs to walk the reexport_chain specifically for declarative macros, allowing them to inherit inline attributes exactly as glob imports do, while preserving strict visibility rules for standard items.

Fixes #154694

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Apr 6, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 6, 2026

r? @lolbinarycat

rustbot has assigned @lolbinarycat.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: rustdoc
  • rustdoc expanded to 9 candidates
  • Random selection from GuillaumeGomez, camelid, fmease, lolbinarycat, notriddle

@rustbot

This comment has been minimized.

@shivendra02467 shivendra02467 force-pushed the fix-rustdoc-macro-inline branch from 9ada003 to e571df1 Compare April 6, 2026 17:20
@lolbinarycat
Copy link
Copy Markdown
Contributor

lolbinarycat commented Apr 6, 2026

thanks for the contribution!

I haven't looked at the code in-depth yet, but this will need a regression test, I would recommend the rustdoc-html test suite. If you have any issues creating a test, please let me know, both so I can help and so the documentation can be improved for future contributors.

EDIT: nvm there is a regression test, not sure how i missed that.

@shivendra02467
Copy link
Copy Markdown
Contributor Author

thanks for the contribution!

I haven't looked at the code in-depth yet, but this will need a regression test, I would recommend the rustdoc-html test suite. If you have any issues creating a test, please let me know, both so I can help and so the documentation can be improved for future contributors.

EDIT: nvm there is a regression test, not sure how i missed that.

No worries at all! Thanks for taking a look. Take your time with the review, and just let me know if you need any adjustments to the test or the logic once you get a chance to dig into it.

@lolbinarycat
Copy link
Copy Markdown
Contributor

The logic is a bit naive, reexport_chain has no knowledge of doc(hidden), so we need to handle that properly.

Specifically, as we walk backwards through the import chain1, if we hit a doc(hidden) attribute before or at the same time as we find a doc(inline) attribute, we need to stop searching and say the macro is hidden.

The code already had a decent bit of duplication going on, and the extra logic would only add to that, so please factor out the check (or at least a decent portion of it) into a utility function or method, perhaps named something like should_macro_reexport_be_hidden.

Modified test with extra details in comments
// Regression test for <https://github.com/rust-lang/rust/issues/154694>.
// The goal is to ensure that declarative macros re-exported by name
// inherit the `#[doc(inline)]` attribute from intermediate re-exports,
// matching the behavior of glob re-exports.

#![crate_name = "foo"]

#[macro_use]
mod macros {
    #[macro_export]
    #[doc(hidden)]
    macro_rules! explicit_macro {
        () => {};
    }

    #[macro_export]
    #[doc(hidden)]
    macro_rules! wild_macro {
        () => {};
    }

    #[macro_export]
    #[doc(hidden)]
    macro_rules! actually_hidden_macro {
        () => {};
    }

    #[macro_export]
    #[doc(hidden)]
    macro_rules! actually_hidden_wild_macro {
        () => {};
    }


    #[macro_export]
    #[doc(hidden)]
    macro_rules! actually_hidden_indirect_macro {
        () => {};
    }

}

// We would like to have parity between macro inlining and inlining other items,
// so I'm providing a struct for reference.
#[doc(hidden)]
pub struct HiddenStruct;

#[doc(hidden)]
pub struct IndirectlyHiddenStruct;


pub mod bar {
    mod hidden_explicit {
        #[doc(inline)]
        pub use crate::explicit_macro;
    }

    mod hidden_wild {
        #[doc(inline)]
        pub use crate::wild_macro;
    }

    mod actually_hidden {
        // BUG: as demonstrated by the `actually_hidden_struct` module, when both
        // `doc(hidden)` and `doc(inline)` are specified, `doc(hidden)`
        // should take priority.
        #[doc(hidden)]
        #[doc(inline)]
        pub use crate::actually_hidden_macro;
    }

    mod actually_hidden_indirect_inner {
        #[doc(inline)]
        pub use crate::actually_hidden_indirect_macro;
    }

    mod actually_hidden_indirect {
        // BUG: when there is a chain of imports, we should stop looking as soon as soon as we hit
        // something with `doc(hidden)`.
        // IMO this is the more important of the two bugs.
        #[doc(hidden)]
        pub use super::actually_hidden_indirect_inner::actually_hidden_indirect_macro;
    }

    mod actually_hidden_indirect_struct_inner {
        #[doc(inline)]
        pub use crate::IndirectlyHiddenStruct;
    }

    mod actually_hidden_indirect_struct {
        #[doc(hidden)]
        pub use super::actually_hidden_indirect_struct_inner::IndirectlyHiddenStruct;
    }

    mod actually_hidden_wild {
        #[doc(hidden)]
        #[doc(inline)]
        pub use crate::actually_hidden_wild_macro;
    }

    mod actually_hidden_struct {
        #[doc(inline)]
        #[doc(hidden)]
        pub use crate::HiddenStruct;
    }


    // First, we check that the explicitly named macro inherits the inline attribute
    // from `hidden_explicit` and is successfully rendered.
    //@ has 'foo/bar/macro.explicit_macro.html'
    //@ has 'foo/bar/index.html' '//a[@href="macro.explicit_macro.html"]' 'explicit_macro'
    pub use self::hidden_explicit::explicit_macro;

    // Next, we ensure that the glob-imported macro continues to render correctly
    // as a control case.
    //@ has 'foo/bar/macro.wild_macro.html'
    //@ has 'foo/bar/index.html' '//a[@href="macro.wild_macro.html"]' 'wild_macro'
    pub use self::hidden_wild::*;

    //@ !has 'foo/bar/macro.actually_hidden_macro.html'
    pub use self::actually_hidden::actually_hidden_macro;
    //@ !has 'foo/bar/macro.actually_hidden_wild_macro.html'
    pub use self::actually_hidden_wild::*;
    //@ !has 'foo/bar/struct.HiddenStruct.html'
    pub use self::actually_hidden_struct::HiddenStruct;
    //@ !has 'foo/bar/macro.actually_hidden_indirect_macro.html'
    pub use self::actually_hidden_indirect::actually_hidden_indirect_macro;
    //@ !has 'foo/bar/struct.IndirectlyHiddenStruct.html'
    pub use self::actually_hidden_indirect_struct::IndirectlyHiddenStruct;
}

Footnotes

  1. I don't know if reexport_chain walks forwards or backwards by default, will require some experimentation.

@lolbinarycat
Copy link
Copy Markdown
Contributor

@rustbot author

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 6, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 6, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 6, 2026
@shivendra02467 shivendra02467 force-pushed the fix-rustdoc-macro-inline branch from e571df1 to 77505ae Compare April 6, 2026 22:35
@shivendra02467
Copy link
Copy Markdown
Contributor Author

Thanks for the detailed test and catching the doc(hidden) edge case!

I've factored the check into a helper named macro_reexport_is_inline (kept the positive naming to avoid inverting the existing booleans). It correctly returns the moment it hits doc(hidden).

Regarding your footnote: I verified that reexport_chain walks backwards by default. A standard .iter() hits the doc(hidden) node first, so the precedence works perfectly! I've also included your comments in the test with the conversational comments trimmed.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 6, 2026
Copy link
Copy Markdown
Contributor

@lolbinarycat lolbinarycat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small suggestions, but I think it looks good otherwise!

View changes since this review

When explicitly re-exporting a declarative macro by name, rustdoc
previously bypassed intermediate re-exports and dropped `#[doc(inline)]`
attributes, causing the macro to be incorrectly stripped if the original
definition was `#[doc(hidden)]`.

This updates `generate_item_with_correct_attrs` to walk the
`reexport_chain` specifically for declarative macros, allowing them to
inherit inline attributes exactly as glob imports do, while preserving
strict visibility rules for standard items.
@shivendra02467 shivendra02467 force-pushed the fix-rustdoc-macro-inline branch from 77505ae to f8d3c27 Compare April 7, 2026 06:23
@lolbinarycat
Copy link
Copy Markdown
Contributor

@bors r+ rollup

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Apr 7, 2026

📌 Commit f8d3c27 has been approved by lolbinarycat

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 7, 2026
rust-bors bot pushed a commit that referenced this pull request Apr 8, 2026
Rollup of 4 pull requests

Successful merges:

 - #154460 (Deduplication: Pulled common logic out from lower_const_arg_struct)
 - #154609 (Enable `#[diagnostic::on_const]` for local impls)
 - #154678 (Introduce #[diagnostic::on_move] on `Rc`)
 - #154902 (rustdoc: Inherit inline attributes for declarative macros)
rust-timer added a commit that referenced this pull request Apr 8, 2026
Rollup merge of #154902 - shivendra02467:fix-rustdoc-macro-inline, r=lolbinarycat

rustdoc: Inherit inline attributes for declarative macros

When explicitly re-exporting a declarative macro by name, rustdoc previously bypassed intermediate re-exports and dropped `#[doc(inline)]` attributes, causing the macro to be incorrectly stripped if the original definition was `#[doc(hidden)]`.

This updates `generate_item_with_correct_attrs` to walk the `reexport_chain` specifically for declarative macros, allowing them to inherit inline attributes exactly as glob imports do, while preserving strict visibility rules for standard items.

Fixes #154694
@rust-bors rust-bors bot merged commit 084a82e into rust-lang:main Apr 8, 2026
11 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Apr 8, 2026
@shivendra02467 shivendra02467 deleted the fix-rustdoc-macro-inline branch April 8, 2026 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re-export a declarative macro isn't rendered by rustdoc if named explicitly

3 participants