Skip to content

Commit

Permalink
Rollup merge of rust-lang#81021 - CraftSpider:rustdoc-remove-import, …
Browse files Browse the repository at this point in the history
…r=jyn514

Remove doctree::Import

Per the title. Part of cleaning up doctree
  • Loading branch information
m-ou-se authored Jan 16, 2021
2 parents 9064f1a + 31b17f5 commit 69dd8f2
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 116 deletions.
176 changes: 85 additions & 91 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ impl Clean<ExternalCrate> for CrateNum {
impl Clean<Item> for doctree::Module<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let mut items: Vec<Item> = vec![];
items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
items.extend(self.mods.iter().map(|x| x.clean(cx)));
items.extend(self.items.iter().map(|x| x.clean(cx)).flatten());
Expand Down Expand Up @@ -2015,7 +2014,7 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
ItemKind::Fn(ref sig, ref generics, body_id) => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
let items = item_ids
.iter()
.map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx))
Expand All @@ -2034,6 +2033,9 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
ItemKind::ExternCrate(orig_name) => {
return clean_extern_crate(item, name, orig_name, cx);
}
ItemKind::Use(path, kind) => {
return clean_use_statement(item, name, path, kind, cx);
}
_ => unreachable!("not yet converted"),
};

Expand Down Expand Up @@ -2155,105 +2157,97 @@ fn clean_extern_crate(
}]
}

impl Clean<Vec<Item>> for doctree::Import<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
// We need this comparison because some imports (for std types for example)
// are "inserted" as well but directly by the compiler and they should not be
// taken into account.
if self.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::StdImports) {
return Vec::new();
}

let (doc_meta_item, please_inline) = self.attrs.lists(sym::doc).get_word_attr(sym::inline);
let pub_underscore = self.vis.node.is_pub() && self.name == kw::Underscore;

if pub_underscore && please_inline {
rustc_errors::struct_span_err!(
cx.tcx.sess,
doc_meta_item.unwrap().span(),
E0780,
"anonymous imports cannot be inlined"
)
.span_label(self.span, "anonymous import")
.emit();
}
fn clean_use_statement(
import: &hir::Item<'_>,
name: Symbol,
path: &hir::Path<'_>,
kind: hir::UseKind,
cx: &DocContext<'_>,
) -> Vec<Item> {
// We need this comparison because some imports (for std types for example)
// are "inserted" as well but directly by the compiler and they should not be
// taken into account.
if import.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::StdImports) {
return Vec::new();
}

let (doc_meta_item, please_inline) = import.attrs.lists(sym::doc).get_word_attr(sym::inline);
let pub_underscore = import.vis.node.is_pub() && name == kw::Underscore;

if pub_underscore && please_inline {
rustc_errors::struct_span_err!(
cx.tcx.sess,
doc_meta_item.unwrap().span(),
E0780,
"anonymous imports cannot be inlined"
)
.span_label(import.span, "anonymous import")
.emit();
}

// We consider inlining the documentation of `pub use` statements, but we
// forcefully don't inline if this is not public or if the
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let mut denied = !self.vis.node.is_pub()
|| pub_underscore
|| self.attrs.iter().any(|a| {
a.has_name(sym::doc)
&& match a.meta_item_list() {
Some(l) => {
attr::list_contains_name(&l, sym::no_inline)
|| attr::list_contains_name(&l, sym::hidden)
}
None => false,
// We consider inlining the documentation of `pub use` statements, but we
// forcefully don't inline if this is not public or if the
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let mut denied = !import.vis.node.is_pub()
|| pub_underscore
|| import.attrs.iter().any(|a| {
a.has_name(sym::doc)
&& match a.meta_item_list() {
Some(l) => {
attr::list_contains_name(&l, sym::no_inline)
|| attr::list_contains_name(&l, sym::hidden)
}
});
// Also check whether imports were asked to be inlined, in case we're trying to re-export a
// crate in Rust 2018+
let path = self.path.clean(cx);
let inner = if self.glob {
if !denied {
let mut visited = FxHashSet::default();
if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
return items;
None => false,
}
});

// Also check whether imports were asked to be inlined, in case we're trying to re-export a
// crate in Rust 2018+
let def_id = cx.tcx.hir().local_def_id(import.hir_id).to_def_id();
let path = path.clean(cx);
let inner = if kind == hir::UseKind::Glob {
if !denied {
let mut visited = FxHashSet::default();
if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
return items;
}
Import::new_glob(resolve_use_source(cx, path), true)
} else {
let name = self.name;
if !please_inline {
if let Res::Def(DefKind::Mod, did) = path.res {
if !did.is_local() && did.index == CRATE_DEF_INDEX {
// if we're `pub use`ing an extern crate root, don't inline it unless we
// were specifically asked for it
denied = true;
}
}
Import::new_glob(resolve_use_source(cx, path), true)
} else {
if !please_inline {
if let Res::Def(DefKind::Mod, did) = path.res {
if !did.is_local() && did.index == CRATE_DEF_INDEX {
// if we're `pub use`ing an extern crate root, don't inline it unless we
// were specifically asked for it
denied = true;
}
}
if !denied {
let mut visited = FxHashSet::default();
}
if !denied {
let mut visited = FxHashSet::default();

if let Some(mut items) = inline::try_inline(
if let Some(mut items) = inline::try_inline(
cx,
cx.tcx.parent_module(import.hir_id).to_def_id(),
path.res,
name,
Some(import.attrs),
&mut visited,
) {
items.push(Item::from_def_id_and_parts(
def_id,
None,
ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
cx,
cx.tcx.parent_module(self.id).to_def_id(),
path.res,
name,
Some(self.attrs),
&mut visited,
) {
items.push(Item {
name: None,
attrs: box self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
kind: box ImportItem(Import::new_simple(
self.name,
resolve_use_source(cx, path),
false,
)),
});
return items;
}
));
return items;
}
Import::new_simple(name, resolve_use_source(cx, path), true)
};
}
Import::new_simple(name, resolve_use_source(cx, path), true)
};

vec![Item {
name: None,
attrs: box self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
kind: box ImportItem(inner),
}]
}
vec![Item::from_def_id_and_parts(def_id, None, ImportItem(inner), cx)]
}

impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
Expand Down
14 changes: 0 additions & 14 deletions src/librustdoc/doctree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//! manner (and with prettier names) before cleaning.
crate use self::StructType::*;

use rustc_ast as ast;
use rustc_span::{self, Span, Symbol};

use rustc_hir as hir;
Expand All @@ -11,7 +10,6 @@ crate struct Module<'hir> {
crate name: Option<Symbol>,
crate where_outer: Span,
crate where_inner: Span,
crate imports: Vec<Import<'hir>>,
crate mods: Vec<Module<'hir>>,
crate id: hir::HirId,
// (item, renamed)
Expand All @@ -28,7 +26,6 @@ impl Module<'hir> {
id: hir::CRATE_HIR_ID,
where_outer: rustc_span::DUMMY_SP,
where_inner: rustc_span::DUMMY_SP,
imports: Vec::new(),
mods: Vec::new(),
items: Vec::new(),
foreigns: Vec::new(),
Expand All @@ -48,17 +45,6 @@ crate enum StructType {
Unit,
}

#[derive(Debug)]
crate struct Import<'hir> {
crate name: Symbol,
crate id: hir::HirId,
crate vis: &'hir hir::Visibility<'hir>,
crate attrs: &'hir [ast::Attribute],
crate path: &'hir hir::Path<'hir>,
crate glob: bool,
crate span: Span,
}

crate fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {
match *vdata {
hir::VariantData::Struct(..) => Plain,
Expand Down
10 changes: 1 addition & 9 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,15 +316,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}

om.imports.push(Import {
name,
id: item.hir_id,
vis: &item.vis,
attrs: &item.attrs,
path,
glob: is_glob,
span: item.span,
});
om.items.push((item, renamed))
}
hir::ItemKind::Mod(ref m) => {
om.mods.push(self.visit_mod_contents(
Expand Down
3 changes: 3 additions & 0 deletions src/test/rustdoc-json/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
# and then create `yourtest.expected` by stripping unnecessary details from `yourtest.json`. If
# you're on windows, replace `\` with `/`.

# WARNING: The error messages produced by this may be misleading, in the case of list re-ordering
# it may point to apparently unrelated keys.

import copy
import sys
import json
Expand Down
4 changes: 2 additions & 2 deletions src/test/rustdoc-json/nested.expected
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"inner": {
"is_crate": false,
"items": [
"0:7",
"0:4"
"0:4",
"0:7"
]
},
"kind": "module",
Expand Down

0 comments on commit 69dd8f2

Please sign in to comment.