Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add chapter for re-exports in the rustdoc book #109456

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/doc/rustdoc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [How to write documentation](how-to-write-documentation.md)
- [What to include (and exclude)](write-documentation/what-to-include.md)
- [The `#[doc]` attribute](write-documentation/the-doc-attribute.md)
- [Re-exports](write-documentation/re-exports.md)
- [Linking to items by name](write-documentation/linking-to-items-by-name.md)
- [Documentation tests](write-documentation/documentation-tests.md)
- [Rustdoc-specific lints](lints.md)
Expand Down
101 changes: 101 additions & 0 deletions src/doc/rustdoc/src/write-documentation/re-exports.md
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably want to specifically mention how attribute merging works:

Attributes

When an item is inlined, its doc comments and most of its attributes will be inlined along with it.

Attribute Inlined? Notes
#[doc=""] Yes Intra-doc links are resolved relative to where the doc comment is defined (/// is syntax sugar for doc string attributes).
#[doc(cfg(..))] Yes
#[deprecated] Yes Intra-doc links are resolved relative to where the description is defined.
#[doc(alias="")] No
#[doc(hidden)] No Hiding an item interacts with inlining the same way making an item private does.

All other attributes are inherited when inlined, so that the documentation matches the behavior if the inlined item was directly defined at the spot where it's shown.

Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Re-exports

Let's start by explaining what are re-exports. To do so, we will use an example where we are
writing a library (named `lib`) with some types dispatched in sub-modules:

```rust
pub mod sub_module1 {
pub struct Foo;
}
pub mod sub_module2 {
pub struct AnotherFoo;
}
```

Users can import them like this:

```rust,ignore
use lib::sub_module1::Foo;
use lib::sub_module2::AnotherFoo;
```

But what if you want the types to be available directly at the crate root or if we don't want the
modules to be visible for users? That's where re-exports come in:

```rust
// `sub_module1` and `sub_module2` are not visible outside.
mod sub_module1 {
pub struct Foo;
}
mod sub_module2 {
pub struct AnotherFoo;
}

// We re-export both types:
pub use crate::sub_module1::Foo;
pub use crate::sub_module2::AnotherFoo;
```

And now users will be able to do:

```rust,ignore
use lib::{Foo, AnotherFoo};
```

And since both `sub_module1` and `sub_module2` are private, users won't be able to import them.

Now what's interesting is that the generated documentation for this crate will show both `Foo` and
`AnotherFoo` directly at the crate root, meaning they have been inlined. There are a few rules to
know whether or not a re-exported item will be inlined.

## Inlining rules

If a public item comes from a private module, it will be inlined:

```rust
mod private_module {
pub struct Public;
}

pub mod public_mod {
// `Public` will inlined here since `private_module` is private.
pub use super::private_module::Public;
}

// `Public` will not be inlined here since `public_mod` is public.
pub use self::public_mod::Public;
```

Likewise, if an item inherits has `#[doc(hidden)]` or inherits it (from any of its parents), it
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Likewise, if an item inherits has `#[doc(hidden)]` or inherits it (from any of its parents), it
Likewise, if an item has `#[doc(hidden)]` or inherits it (from any of its parents), it

will be inlined:

```rust
#[doc(hidden)]
pub mod public_mod {
pub struct Public;
}

#[doc(hidden)]
pub struct Hidden;

// `Public` be inlined since its parent (`public_mod`) has `#[doc(hidden)]`.
pub use self::public_mod::Public;
// `Hidden` be inlined since it has `#[doc(hidden)]`.
pub use self::Hidden;
```

## Inlining with `#[doc(inline)]`

You can use the `#[doc(inline)]` attribute if you want to force an item to be inlined:

```rust
pub mod public_mod {
pub struct Public;
}

#[doc(inline)]
pub use self::public_mod::Public;
```

With this code, even though `public_mod::Public` is public and present in the documentation, the
`Public` type will be present both at the crate root and in the `public_mod` module.