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

Remove doctree::Import #81021

Merged
merged 4 commits into from
Jan 16, 2021
Merged
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
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 @@ -2019,7 +2018,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 @@ -2038,6 +2037,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 @@ -2159,105 +2161,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"
CraftSpider marked this conversation as resolved.
Show resolved Hide resolved
]
},
"kind": "module",
Expand Down