Skip to content

Are publicly re-exported items from a doc(hidden) module considered public API? #117845

Open
@obi1kenobi

Description

@obi1kenobi

Let's look at this example from the doc comment in #117810:

#[doc(hidden)]
pub mod foo {
    pub struct Bar;
}

pub use foo::Bar;

To me, this seems like a public re-export of an intended-to-be-public item. In other words, when I see this code, I expect its doc(hidden) semantics to be that it is the module that is hidden, but non-hidden ways to access its contents are public API and "fair game." In my interpretation, if the programmer intended that to not be the case, they could have hidden the re-export (or pub struct Bar itself).

If pub struct Bar is always considered hidden regardless of re-exports (whether themselves hidden or not), I think that has strange implications for what is and is not public API. In that interpretation, the re-export is public API but the item it points to is not public API ... which is just confusing. It seems like it says "I make it part of the public API that this non-public-API type reserves a name in the public API" and nothing else. That's just strange! What public API operations are allowed over that re-export item? It feels to me like the answer is that the item is "neither here nor there" with respect to being public API or not.

It also seems to risk opening a terrible can of worms with further edge cases:

mod defn {
    pub struct Example;
}

#[doc(hidden)]
pub mod hide {
    pub use crate::Example as Example;
}

// Here, `Example` is public API.
pub use defn::Example;

// Replace it with the below code and `Example` is no longer public API.
// Worse, we can't distinguish between these two cases via rustdoc JSON,
// so this interpretation would permanently break cargo-semver-checks.
// pub use hide::Example;

For these reasons, I think a better interpretation of whether an item is doc(hidden) is one based on reachability: if you can reach the item without going through any doc(hidden) items (the item itself + any modules and re-exports), it is not hidden. If all paths require going through at least one hidden item, the item is hidden. This is also how visibility works as well — the pub-in-priv trick wouldn't work otherwise — so I think it makes a lot of sense for doc(hidden) to work that way too.

Originally posted by @obi1kenobi in #117810 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-rustdoc-jsonArea: Rustdoc JSON backendT-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions