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

rustdoc: Allow inlining of reexported crates and crate items #46296

Closed
panicbit opened this issue Nov 27, 2017 · 1 comment
Closed

rustdoc: Allow inlining of reexported crates and crate items #46296

panicbit opened this issue Nov 27, 2017 · 1 comment
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@panicbit
Copy link
Contributor

#[doc(inline)]
pub extern crate foo;

Could show foo as if it was a module.

extern crate foo;
#[doc(inline)]
pub use foo::*;

Could inline the reexported items as if foo was a module.

@TimNN TimNN added T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Nov 28, 2017
@QuietMisdreavus
Copy link
Member

Some mentoring notes. I'm planning on walking @DebugSteven through this.

First, this is only relevant for 2015 edition, since 2018 edition won't have it as an extern crate anyway. However, this issue is still relevant for 2015 code, so let's take a look...

The relevant spot where extern crate statements are processed is in clean/mod.rs:

impl Clean<Item> for doctree::ExternCrate {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
visibility: self.vis.clean(cx),
stability: None,
deprecation: None,
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
}
}
}

Fortunately, the spot where use statements are processed is right below it! We need to copy some code from this to make sure we do the same thing.

The rough idea i have for the new code goes like this:

  • Change this Clean impl to return a Vec<Item> instead of a single Item.
  • Check the ExternCrate to make sure it's pub and is marked with #[doc(inline)]. If it is, attempt to inline it by calling inline::try_inline. If it succeeds, return the list of new items.
  • If we didn't try inlining or it failed (by returning None), create the single Item as before, stick it in a Vec, and return that instead.

That middle part is where it gets interesting, because try_inline assumes we have a Def on hand from the Import. Fortunately, we can effectively make one up on the spot, since we have the CrateNum on hand and we can make up a DefId that points to the crate root. Once we have that, all we need is to wrap it with Def::Mod since we know we're pointing at a module:

Def::Mod(DefId {
    krate: self.cnum,
    index: CRATE_DEF_INDEX,
})

All the rest of the arguments to try_inline are already on hand or can be created on the spot.


To check the extern crate statement for the right conditions, we can copy code from the doctree::Import impl:

let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
a.name() == "doc" && match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, "no_inline") ||
attr::list_contains_name(&l, "hidden"),
None => false,
}
});

This is performing similar checks to what we need, though we'll need to tweak them slightly. The ExternCrate type has the same vis and attrs fields, so we can use the same structure to check for whether it's pub and for inspecting the attributes. Note that that code is checking for whether it shouldn't inline a use statement, so it's checking for whether it's non-pub or whether it has #[doc(no_inline)] or #[doc(hidden)]. However, we want to check for whether we should inline our statement, so we want to check for #[doc(inline)]. The same check can be used, but the two inner statements can be replaced with one, to compare against "inline".

pietroalbini added a commit to pietroalbini/rust that referenced this issue Jan 12, 2019
…umeGomez

rustdoc: Allow inlining of reexported crates and crate items

Fixes rust-lang#46296

This PR checks for when a `pub extern crate` statement has a `#[doc(inline)]` attribute & inlines its contents. Code is based off of the inlining statements for `pub use` statements.
Centril added a commit to Centril/rust that referenced this issue Jan 13, 2019
…umeGomez

rustdoc: Allow inlining of reexported crates and crate items

Fixes rust-lang#46296

This PR checks for when a `pub extern crate` statement has a `#[doc(inline)]` attribute & inlines its contents. Code is based off of the inlining statements for `pub use` statements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants