rust-lang / rust-lang/rust

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

Open
#117,845 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-rustdoc-json T-rustdoc
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

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 https://github.com/rust-lang/rust/issues/117810#issuecomment-1806850905

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the referenced discussion in issue #117810 and compare the two re-export examples in this issue. Then inspect how rustdoc JSON represents these cases and consider the stated cargo-semver-checks impact; done means the reachability semantics and resulting public-API behavior are resolved.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.