From ad9933ee757ce482306380d974828d521c7c7209 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 18 Oct 2020 12:36:51 -0400 Subject: [PATCH 01/27] [extremely broken] try to get rid of doctree this compiles but does not run --- src/librustdoc/clean/mod.rs | 96 ++++++++++++++++++++++++++++------- src/librustdoc/clean/utils.rs | 10 ++-- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9d84089eb405c..5acabd44064cb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -29,6 +29,7 @@ use rustc_span::{self, ExpnKind, Pos}; use rustc_typeck::hir_ty_to_ty; use std::collections::hash_map::Entry; +use std::collections::BTreeMap; use std::default::Default; use std::hash::Hash; use std::rc::Rc; @@ -60,6 +61,12 @@ impl, U> Clean> for [T] { } } +impl, U> Clean> for BTreeMap { + fn clean(&self, cx: &DocContext<'_>) -> Vec { + self.values().map(|x| x.clean(cx)).collect() + } +} + impl, U, V: Idx> Clean> for IndexVec { fn clean(&self, cx: &DocContext<'_>) -> IndexVec { self.iter().map(|x| x.clean(cx)).collect() @@ -221,6 +228,72 @@ impl Clean for CrateNum { } } +impl Clean for hir::Item<'_> { + fn clean(&self, _cx: &DocContext<'_>) -> Item { + unimplemented!() + } +} + +impl Clean for hir::Crate<'_> { + fn clean(&self, cx: &DocContext<'_>) -> Item { + // TODO: use tcx.crate_name instead + let name = None; + let attrs = self.item.attrs.clean(cx); + + // Get _all_ the items! + let mut items = self.items.clean(cx); + items.extend(self.exported_macros.clean(cx)); + items.extend(self.trait_items.clean(cx)); + items.extend(self.impl_items.clean(cx)); + // NOTE: bodies intentionally skipped + + items.extend(self.trait_impls.iter().flat_map(|(_trait, impls)| { + impls.into_iter().map(|&impl_| cx.tcx.hir().item(impl_).clean(cx)) + })); + items.extend(self.modules.clean(cx).into_iter().flatten()); + items.extend(self.proc_macros.iter().map(|hir_id| { + let _def_id = hir_id.owner.local_def_index; + // TODO: look how `rustc_metadata::rmeta::encoder` does this + unimplemented!() + })); + + // determine if we should display the inner contents or + // the outer `mod` item for the source code. + // TODO: for the crate root, I think this should always be `self.item.span`? + let span = { + let sm = cx.sess().source_map(); + let outer = sm.lookup_char_pos(self.item.span.lo()); + let inner = sm.lookup_char_pos(self.item.module.inner.lo()); + if outer.file.start_pos == inner.file.start_pos { + // mod foo { ... } + self.item.span + } else { + // mod foo; (and a separate SourceFile for the contents) + self.item.module.inner + } + }; + + let id = hir::CRATE_HIR_ID; + Item { + name, + attrs, + source: span.clean(cx), + visibility: Visibility::Public, + stability: cx.stability(id), + deprecation: cx.deprecation(id).clean(cx), + def_id: cx.tcx.hir().local_def_id(id).to_def_id(), + kind: ModuleItem(Module { is_crate: true, items }), + } + } +} + +impl Clean> for hir::ModuleItems { + fn clean(&self, _cx: &DocContext<'_>) -> Vec { + unimplemented!() + } +} + +/* impl Clean for doctree::Module<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { // maintain a stack of mod ids, for doc comment path resolution @@ -276,6 +349,7 @@ impl Clean for doctree::Module<'_> { } } } +*/ impl Clean for [ast::Attribute] { fn clean(&self, cx: &DocContext<'_>) -> Attributes { @@ -718,7 +792,6 @@ impl Clean for hir::Generics<'_> { impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { fn clean(&self, cx: &DocContext<'_>) -> Generics { use self::WherePredicate as WP; - use std::collections::BTreeMap; let (gens, preds) = *self; @@ -2280,24 +2353,9 @@ impl Clean for doctree::ForeignItem<'_> { } } -impl Clean for doctree::Macro { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item::from_def_id_and_parts( - self.def_id, - Some(self.name), - MacroItem(Macro { - source: format!( - "macro_rules! {} {{\n{}}}", - self.name, - self.matchers - .iter() - .map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) }) - .collect::() - ), - imported_from: self.imported_from.clean(cx), - }), - cx, - ) +impl Clean for hir::MacroDef<'_> { + fn clean(&self, _cx: &DocContext<'_>) -> Item { + unimplemented!() } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 22917fbceb48a..14f49a2d38b0b 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -24,7 +24,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { use crate::visit_lib::LibEmbargoVisitor; let krate = cx.tcx.hir().krate(); - let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate); + //let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate); let mut r = cx.renderinfo.get_mut(); r.deref_trait_did = cx.tcx.lang_items().deref_trait(); @@ -41,10 +41,10 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { // Clean the crate, translating the entire librustc_ast AST to one that is // understood by rustdoc. - let mut module = module.clean(cx); + let mut krate = krate.clean(cx); let mut masked_crates = FxHashSet::default(); - match module.kind { + match krate.kind { ItemKind::ModuleItem(ref module) => { for it in &module.items { // `compiler_builtins` should be masked too, but we can't apply @@ -62,7 +62,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx); { - let m = match module.kind { + let m = match krate.kind { ItemKind::ModuleItem(ref mut m) => m, _ => unreachable!(), }; @@ -92,7 +92,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { name, version: None, src, - module: Some(module), + module: Some(krate), externs, primitives, external_traits: cx.external_traits.clone(), From 7b8c5aa262655bc24114a1d461d653f552064ddb Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 18 Oct 2020 15:29:21 -0400 Subject: [PATCH 02/27] implement macros --- src/librustdoc/clean/mod.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5acabd44064cb..f7748a8068829 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2354,8 +2354,30 @@ impl Clean for doctree::ForeignItem<'_> { } impl Clean for hir::MacroDef<'_> { - fn clean(&self, _cx: &DocContext<'_>) -> Item { - unimplemented!() + fn clean(&self, cx: &DocContext<'_>) -> Item { + let tts: Vec<_> = self.ast.body.inner_tokens().trees().collect(); + // Extract the spans of all matchers. They represent the "interface" of the macro. + let matchers = tts.chunks(4).map(|arm| arm[0].span()); + + Item { + name: Some(self.ident.name.to_string()), // TODO: this should store a Symbol + attrs: self.attrs.clean(cx), + source: self.span.clean(cx), + visibility: Public, + stability: cx.stability(self.hir_id), + deprecation: cx.deprecation(self.hir_id).clean(cx), + def_id: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(), + kind: MacroItem(Macro { + source: format!( + "macro_rules! {} {{\n{}}}", + self.ident.name, + matchers + .map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) }) + .collect::() + ), + imported_from: None, + }), + } } } From 0b05cee95f8120bc792d5d2403328d0df398d77a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 18 Oct 2020 15:33:37 -0400 Subject: [PATCH 03/27] Remove dead code --- src/librustdoc/doctree.rs | 65 ----- src/librustdoc/lib.rs | 1 - src/librustdoc/visit_ast.rs | 545 ------------------------------------ 3 files changed, 611 deletions(-) delete mode 100644 src/librustdoc/visit_ast.rs diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index bd9262191356f..93053704a16df 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -10,62 +10,6 @@ use rustc_hir as hir; use rustc_hir::def_id::CrateNum; use rustc_hir::HirId; -crate struct Module<'hir> { - crate name: Option, - crate attrs: &'hir [ast::Attribute], - crate where_outer: Span, - crate where_inner: Span, - crate extern_crates: Vec>, - crate imports: Vec>, - crate structs: Vec>, - crate unions: Vec>, - crate enums: Vec>, - crate fns: Vec>, - crate mods: Vec>, - crate id: hir::HirId, - crate typedefs: Vec>, - crate opaque_tys: Vec>, - crate statics: Vec>, - crate constants: Vec>, - crate traits: Vec>, - crate impls: Vec>, - crate foreigns: Vec>, - crate macros: Vec, - crate proc_macros: Vec, - crate trait_aliases: Vec>, - crate is_crate: bool, -} - -impl Module<'hir> { - crate fn new(name: Option, attrs: &'hir [ast::Attribute]) -> Module<'hir> { - Module { - name, - id: hir::CRATE_HIR_ID, - where_outer: rustc_span::DUMMY_SP, - where_inner: rustc_span::DUMMY_SP, - attrs, - extern_crates: Vec::new(), - imports: Vec::new(), - structs: Vec::new(), - unions: Vec::new(), - enums: Vec::new(), - fns: Vec::new(), - mods: Vec::new(), - typedefs: Vec::new(), - opaque_tys: Vec::new(), - statics: Vec::new(), - constants: Vec::new(), - traits: Vec::new(), - impls: Vec::new(), - foreigns: Vec::new(), - macros: Vec::new(), - proc_macros: Vec::new(), - trait_aliases: Vec::new(), - is_crate: false, - } - } -} - #[derive(Debug, Clone, Copy)] crate enum StructType { /// A braced struct @@ -186,15 +130,6 @@ crate struct ForeignItem<'hir> { crate kind: &'hir hir::ForeignItemKind<'hir>, } -// For Macro we store the DefId instead of the NodeId, since we also create -// these imported macro_rules (which only have a DUMMY_NODE_ID). -crate struct Macro { - crate name: Symbol, - crate def_id: hir::def_id::DefId, - crate matchers: Vec, - crate imported_from: Option, -} - crate struct ExternCrate<'hir> { crate name: Symbol, crate hir_id: HirId, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index a88efba77b41c..e15d11da1b4a9 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -82,7 +82,6 @@ mod json; mod markdown; mod passes; mod theme; -mod visit_ast; mod visit_lib; pub fn main() { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs deleted file mode 100644 index 76fae11291805..0000000000000 --- a/src/librustdoc/visit_ast.rs +++ /dev/null @@ -1,545 +0,0 @@ -//! The Rust AST Visitor. Extracts useful information and massages it into a form -//! usable for `clean`. - -use rustc_ast as ast; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir as hir; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_hir::Node; -use rustc_middle::middle::privacy::AccessLevel; -use rustc_middle::ty::TyCtxt; -use rustc_span::hygiene::MacroKind; -use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{self, Span}; - -use std::mem; - -use crate::clean::{self, AttributesExt, NestedAttributesExt}; -use crate::core; -use crate::doctree::*; - -// FIXME: Should this be replaced with tcx.def_path_str? -fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec { - let crate_name = tcx.crate_name(did.krate).to_string(); - let relative = tcx.def_path(did).data.into_iter().filter_map(|elem| { - // extern blocks have an empty name - let s = elem.data.to_string(); - if !s.is_empty() { Some(s) } else { None } - }); - std::iter::once(crate_name).chain(relative).collect() -} - -// Also, is there some reason that this doesn't use the 'visit' -// framework from syntax?. - -crate struct RustdocVisitor<'a, 'tcx> { - cx: &'a mut core::DocContext<'tcx>, - view_item_stack: FxHashSet, - inlining: bool, - /// Are the current module and all of its parents public? - inside_public_path: bool, - exact_paths: FxHashMap>, -} - -impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { - crate fn new(cx: &'a mut core::DocContext<'tcx>) -> RustdocVisitor<'a, 'tcx> { - // If the root is re-exported, terminate all recursion. - let mut stack = FxHashSet::default(); - stack.insert(hir::CRATE_HIR_ID); - RustdocVisitor { - cx, - view_item_stack: stack, - inlining: false, - inside_public_path: true, - exact_paths: FxHashMap::default(), - } - } - - fn store_path(&mut self, did: DefId) { - let tcx = self.cx.tcx; - self.exact_paths.entry(did).or_insert_with(|| def_id_to_path(tcx, did)); - } - - crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { - let mut module = self.visit_mod_contents( - krate.item.span, - krate.item.attrs, - &Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public }, - hir::CRATE_HIR_ID, - &krate.item.module, - None, - ); - // Attach the crate's exported macros to the top-level module: - module - .macros - .extend(krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None))); - module.is_crate = true; - - self.cx.renderinfo.get_mut().exact_paths = self.exact_paths; - - module - } - - fn visit_variant_data( - &mut self, - item: &'tcx hir::Item<'_>, - name: Symbol, - sd: &'tcx hir::VariantData<'_>, - generics: &'tcx hir::Generics<'_>, - ) -> Struct<'tcx> { - debug!("visiting struct"); - let struct_type = struct_type_from_def(&*sd); - Struct { id: item.hir_id, struct_type, name, generics, fields: sd.fields() } - } - - fn visit_union_data( - &mut self, - item: &'tcx hir::Item<'_>, - name: Symbol, - sd: &'tcx hir::VariantData<'_>, - generics: &'tcx hir::Generics<'_>, - ) -> Union<'tcx> { - debug!("visiting union"); - let struct_type = struct_type_from_def(&*sd); - Union { id: item.hir_id, struct_type, name, generics, fields: sd.fields() } - } - - fn visit_enum_def( - &mut self, - it: &'tcx hir::Item<'_>, - name: Symbol, - def: &'tcx hir::EnumDef<'_>, - generics: &'tcx hir::Generics<'_>, - ) -> Enum<'tcx> { - debug!("visiting enum"); - Enum { - name, - variants: def - .variants - .iter() - .map(|v| Variant { name: v.ident.name, id: v.id, def: &v.data }) - .collect(), - generics, - id: it.hir_id, - } - } - - fn visit_fn( - &mut self, - om: &mut Module<'tcx>, - item: &'tcx hir::Item<'_>, - name: Symbol, - decl: &'tcx hir::FnDecl<'_>, - header: hir::FnHeader, - generics: &'tcx hir::Generics<'_>, - body: hir::BodyId, - ) { - debug!("visiting fn"); - let macro_kind = item.attrs.iter().find_map(|a| { - if a.has_name(sym::proc_macro) { - Some(MacroKind::Bang) - } else if a.has_name(sym::proc_macro_derive) { - Some(MacroKind::Derive) - } else if a.has_name(sym::proc_macro_attribute) { - Some(MacroKind::Attr) - } else { - None - } - }); - match macro_kind { - Some(kind) => { - let name = if kind == MacroKind::Derive { - item.attrs - .lists(sym::proc_macro_derive) - .find_map(|mi| mi.ident()) - .expect("proc-macro derives require a name") - .name - } else { - name - }; - - let mut helpers = Vec::new(); - for mi in item.attrs.lists(sym::proc_macro_derive) { - if !mi.has_name(sym::attributes) { - continue; - } - - if let Some(list) = mi.meta_item_list() { - for inner_mi in list { - if let Some(ident) = inner_mi.ident() { - helpers.push(ident.name); - } - } - } - } - - om.proc_macros.push(ProcMacro { name, id: item.hir_id, kind, helpers }); - } - None => { - om.fns.push(Function { id: item.hir_id, decl, name, generics, header, body }); - } - } - } - - fn visit_mod_contents( - &mut self, - span: Span, - attrs: &'tcx [ast::Attribute], - vis: &'tcx hir::Visibility<'_>, - id: hir::HirId, - m: &'tcx hir::Mod<'tcx>, - name: Option, - ) -> Module<'tcx> { - let mut om = Module::new(name, attrs); - om.where_outer = span; - om.where_inner = m.inner; - om.id = id; - // Keep track of if there were any private modules in the path. - let orig_inside_public_path = self.inside_public_path; - self.inside_public_path &= vis.node.is_pub(); - for i in m.item_ids { - let item = self.cx.tcx.hir().expect_item(i.id); - self.visit_item(item, None, &mut om); - } - self.inside_public_path = orig_inside_public_path; - om - } - - /// Tries to resolve the target of a `crate use` statement and inlines the - /// target if it is defined locally and would not be documented otherwise, - /// or when it is specifically requested with `please_inline`. - /// (the latter is the case when the import is marked `doc(inline)`) - /// - /// Cross-crate inlining occurs later on during crate cleaning - /// and follows different rules. - /// - /// Returns `true` if the target has been inlined. - fn maybe_inline_local( - &mut self, - id: hir::HirId, - res: Res, - renamed: Option, - glob: bool, - om: &mut Module<'tcx>, - please_inline: bool, - ) -> bool { - fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool { - while let Some(id) = cx.tcx.hir().get_enclosing_scope(node) { - node = id; - if cx.tcx.hir().attrs(node).lists(sym::doc).has_word(sym::hidden) { - return true; - } - if node == hir::CRATE_HIR_ID { - break; - } - } - false - } - - debug!("maybe_inline_local res: {:?}", res); - - let tcx = self.cx.tcx; - let res_did = if let Some(did) = res.opt_def_id() { - did - } else { - return false; - }; - - let use_attrs = tcx.hir().attrs(id); - // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. - let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline) - || use_attrs.lists(sym::doc).has_word(sym::hidden); - - // For cross-crate impl inlining we need to know whether items are - // reachable in documentation -- a previously nonreachable item can be - // made reachable by cross-crate inlining which we're checking here. - // (this is done here because we need to know this upfront). - if !res_did.is_local() && !is_no_inline { - let attrs = clean::inline::load_attrs(self.cx, res_did); - let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden); - if !self_is_hidden { - if let Res::Def(kind, did) = res { - if kind == DefKind::Mod { - crate::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did) - } else { - // All items need to be handled here in case someone wishes to link - // to them with intra-doc links - self.cx - .renderinfo - .get_mut() - .access_levels - .map - .insert(did, AccessLevel::Public); - } - } - } - return false; - } - - let res_hir_id = match res_did.as_local() { - Some(n) => tcx.hir().local_def_id_to_hir_id(n), - None => return false, - }; - - let is_private = !self.cx.renderinfo.borrow().access_levels.is_public(res_did); - let is_hidden = inherits_doc_hidden(self.cx, res_hir_id); - - // Only inline if requested or if the item would otherwise be stripped. - if (!please_inline && !is_private && !is_hidden) || is_no_inline { - return false; - } - - if !self.view_item_stack.insert(res_hir_id) { - return false; - } - - let ret = match tcx.hir().get(res_hir_id) { - Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => { - let prev = mem::replace(&mut self.inlining, true); - for i in m.item_ids { - let i = self.cx.tcx.hir().expect_item(i.id); - self.visit_item(i, None, om); - } - self.inlining = prev; - true - } - Node::Item(it) if !glob => { - let prev = mem::replace(&mut self.inlining, true); - self.visit_item(it, renamed, om); - self.inlining = prev; - true - } - Node::ForeignItem(it) if !glob => { - let prev = mem::replace(&mut self.inlining, true); - self.visit_foreign_item(it, renamed, om); - self.inlining = prev; - true - } - Node::MacroDef(def) if !glob => { - om.macros.push(self.visit_local_macro(def, renamed.map(|i| i.name))); - true - } - _ => false, - }; - self.view_item_stack.remove(&res_hir_id); - ret - } - - fn visit_item( - &mut self, - item: &'tcx hir::Item<'_>, - renamed: Option, - om: &mut Module<'tcx>, - ) { - debug!("visiting item {:?}", item); - let ident = renamed.unwrap_or(item.ident); - - if item.vis.node.is_pub() { - let def_id = self.cx.tcx.hir().local_def_id(item.hir_id); - self.store_path(def_id.to_def_id()); - } - - match item.kind { - hir::ItemKind::ForeignMod(ref fm) => { - for item in fm.items { - self.visit_foreign_item(item, None, om); - } - } - // If we're inlining, skip private items. - _ if self.inlining && !item.vis.node.is_pub() => {} - hir::ItemKind::GlobalAsm(..) => {} - hir::ItemKind::ExternCrate(orig_name) => { - let def_id = self.cx.tcx.hir().local_def_id(item.hir_id); - om.extern_crates.push(ExternCrate { - cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id).unwrap_or(LOCAL_CRATE), - name: ident.name, - hir_id: item.hir_id, - path: orig_name.map(|x| x.to_string()), - vis: &item.vis, - attrs: &item.attrs, - span: item.span, - }) - } - hir::ItemKind::Use(_, hir::UseKind::ListStem) => {} - hir::ItemKind::Use(ref path, kind) => { - let is_glob = kind == hir::UseKind::Glob; - - // Struct and variant constructors and proc macro stubs always show up alongside - // their definitions, we've already processed them so just discard these. - if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res { - return; - } - - // If there was a private module in the current path then don't bother inlining - // anything as it will probably be stripped anyway. - if item.vis.node.is_pub() && self.inside_public_path { - let please_inline = item.attrs.iter().any(|item| match item.meta_item_list() { - Some(ref list) if item.has_name(sym::doc) => { - list.iter().any(|i| i.has_name(sym::inline)) - } - _ => false, - }); - let ident = if is_glob { None } else { Some(ident) }; - if self.maybe_inline_local( - item.hir_id, - path.res, - ident, - is_glob, - om, - please_inline, - ) { - return; - } - } - - om.imports.push(Import { - name: ident.name, - id: item.hir_id, - vis: &item.vis, - attrs: &item.attrs, - path, - glob: is_glob, - span: item.span, - }); - } - hir::ItemKind::Mod(ref m) => { - om.mods.push(self.visit_mod_contents( - item.span, - &item.attrs, - &item.vis, - item.hir_id, - m, - Some(ident.name), - )); - } - hir::ItemKind::Enum(ref ed, ref gen) => { - om.enums.push(self.visit_enum_def(item, ident.name, ed, gen)) - } - hir::ItemKind::Struct(ref sd, ref gen) => { - om.structs.push(self.visit_variant_data(item, ident.name, sd, gen)) - } - hir::ItemKind::Union(ref sd, ref gen) => { - om.unions.push(self.visit_union_data(item, ident.name, sd, gen)) - } - hir::ItemKind::Fn(ref sig, ref gen, body) => { - self.visit_fn(om, item, ident.name, &sig.decl, sig.header, gen, body) - } - hir::ItemKind::TyAlias(ty, ref gen) => { - let t = Typedef { ty, gen, name: ident.name, id: item.hir_id }; - om.typedefs.push(t); - } - hir::ItemKind::OpaqueTy(ref opaque_ty) => { - let t = OpaqueTy { opaque_ty, name: ident.name, id: item.hir_id }; - om.opaque_tys.push(t); - } - hir::ItemKind::Static(type_, mutability, expr) => { - let s = Static { - type_, - mutability, - expr, - id: item.hir_id, - name: ident.name, - attrs: &item.attrs, - span: item.span, - vis: &item.vis, - }; - om.statics.push(s); - } - hir::ItemKind::Const(type_, expr) => { - // Underscore constants do not correspond to a nameable item and - // so are never useful in documentation. - if ident.name != kw::Underscore { - let s = Constant { type_, expr, id: item.hir_id, name: ident.name }; - om.constants.push(s); - } - } - hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => { - let items = item_ids.iter().map(|ti| self.cx.tcx.hir().trait_item(ti.id)).collect(); - let t = Trait { - is_auto, - unsafety, - name: ident.name, - items, - generics, - bounds, - id: item.hir_id, - attrs: &item.attrs, - }; - om.traits.push(t); - } - hir::ItemKind::TraitAlias(ref generics, ref bounds) => { - let t = TraitAlias { name: ident.name, generics, bounds, id: item.hir_id }; - om.trait_aliases.push(t); - } - - hir::ItemKind::Impl { - unsafety, - polarity, - defaultness, - constness, - defaultness_span: _, - ref generics, - ref of_trait, - self_ty, - ref items, - } => { - // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick - // them up regardless of where they're located. - if !self.inlining && of_trait.is_none() { - let items = - items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); - let i = Impl { - unsafety, - polarity, - defaultness, - constness, - generics, - trait_: of_trait, - for_: self_ty, - items, - attrs: &item.attrs, - id: item.hir_id, - span: item.span, - vis: &item.vis, - }; - om.impls.push(i); - } - } - } - } - - fn visit_foreign_item( - &mut self, - item: &'tcx hir::ForeignItem<'_>, - renamed: Option, - om: &mut Module<'tcx>, - ) { - // If inlining we only want to include public functions. - if self.inlining && !item.vis.node.is_pub() { - return; - } - - om.foreigns.push(ForeignItem { - id: item.hir_id, - name: renamed.unwrap_or(item.ident).name, - kind: &item.kind, - }); - } - - // Convert each `exported_macro` into a doc item. - fn visit_local_macro(&self, def: &'tcx hir::MacroDef<'_>, renamed: Option) -> Macro { - debug!("visit_local_macro: {}", def.ident); - let tts = def.ast.body.inner_tokens().trees().collect::>(); - // Extract the spans of all matchers. They represent the "interface" of the macro. - let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect(); - - Macro { - def_id: self.cx.tcx.hir().local_def_id(def.hir_id).to_def_id(), - name: renamed.unwrap_or(def.ident.name), - matchers, - imported_from: None, - } - } -} From 341ae707a44eaa6db9573fd434a3265f121cd8c2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 18 Oct 2020 20:25:34 -0400 Subject: [PATCH 04/27] [WIP] fill out `Item` --- src/librustdoc/clean/mod.rs | 42 +++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f7748a8068829..b289c0ac6572f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -228,9 +228,47 @@ impl Clean for CrateNum { } } +/* +impl Clean for hir::ItemKind<'_> { + fn clean(&self, _cx: &DocContext<'_>) -> ItemEnum { + match self { + ExternalCrate(name) => + } + } +} +*/ + impl Clean for hir::Item<'_> { - fn clean(&self, _cx: &DocContext<'_>) -> Item { - unimplemented!() + fn clean(&self, cx: &DocContext<'_>) -> Item { + use hir::ItemKind; + + let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); + let name = cx.tcx.item_name(def_id).clean(cx); + let inner = match self.kind { + // TODO: should store Symbol, not String + ItemKind::ExternCrate(renamed) => ExternCrateItem(name.clone(), renamed.clean(cx)), + ItemKind::Use(path, kind) => { + unimplemented!() + } + /* + ImportItem(Import { + kind: kind.clean(cx), + source: path.clean(cx), + }), + */ + _ => unimplemented!(), + }; + + Item { + def_id, + inner, + name: Some(name), + source: cx.tcx.def_span(def_id).clean(cx), + attrs: self.attrs.clean(cx), // should this use tcx.attrs instead? + visibility: self.vis.clean(cx), // TODO: use tcx.visibility once #78077 lands + stability: cx.tcx.lookup_stability(def_id).copied(), + deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx), + } } } From 42b2043b488639248154f296af0d2058463cee05 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 03:13:47 -0400 Subject: [PATCH 05/27] [WIP] fill out ExternCrate --- src/librustdoc/clean/mod.rs | 118 +++++++++++++++++++----------------- src/librustdoc/doctree.rs | 11 +--- 2 files changed, 63 insertions(+), 66 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b289c0ac6572f..fc25a3624506c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -232,25 +232,31 @@ impl Clean for CrateNum { impl Clean for hir::ItemKind<'_> { fn clean(&self, _cx: &DocContext<'_>) -> ItemEnum { match self { - ExternalCrate(name) => + ExternalCrate(name) => } } } */ -impl Clean for hir::Item<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { +enum CleanedModule { + Module(ItemKind), + Inlined(Vec), +} + +impl Clean> for hir::Item<'_> { + fn clean(&self, cx: &DocContext<'_>) -> Vec { use hir::ItemKind; let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); let name = cx.tcx.item_name(def_id).clean(cx); - let inner = match self.kind { + let kind = match self.kind { // TODO: should store Symbol, not String - ItemKind::ExternCrate(renamed) => ExternCrateItem(name.clone(), renamed.clean(cx)), - ItemKind::Use(path, kind) => { - unimplemented!() - } - /* + ItemKind::ExternCrate(renamed) => match clean_extern_crate(self, renamed, cx) { + CleanedModule::Module(inner) => inner, + CleanedModule::Inlined(items) => return items, + }, + ItemKind::Use(path, kind) => unimplemented!(), + /* ImportItem(Import { kind: kind.clean(cx), source: path.clean(cx), @@ -259,16 +265,16 @@ impl Clean for hir::Item<'_> { _ => unimplemented!(), }; - Item { + vec![Item { def_id, - inner, + kind, name: Some(name), source: cx.tcx.def_span(def_id).clean(cx), attrs: self.attrs.clean(cx), // should this use tcx.attrs instead? visibility: self.vis.clean(cx), // TODO: use tcx.visibility once #78077 lands stability: cx.tcx.lookup_stability(def_id).copied(), deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx), - } + }] } } @@ -279,17 +285,22 @@ impl Clean for hir::Crate<'_> { let attrs = self.item.attrs.clean(cx); // Get _all_ the items! - let mut items = self.items.clean(cx); - items.extend(self.exported_macros.clean(cx)); - items.extend(self.trait_items.clean(cx)); - items.extend(self.impl_items.clean(cx)); + let items = self.items.clean(cx).into_iter().flatten(); + let items = items.chain(self.exported_macros.clean(cx)); + let items = items.chain(self.trait_items.clean(cx)); + let items = items.chain(self.impl_items.clean(cx)); // NOTE: bodies intentionally skipped - items.extend(self.trait_impls.iter().flat_map(|(_trait, impls)| { - impls.into_iter().map(|&impl_| cx.tcx.hir().item(impl_).clean(cx)) - })); - items.extend(self.modules.clean(cx).into_iter().flatten()); - items.extend(self.proc_macros.iter().map(|hir_id| { + let items = items.chain( + self.trait_impls + .iter() + .flat_map(|(_trait, impls)| { + impls.into_iter().map(|&impl_| cx.tcx.hir().item(impl_).clean(cx)) + }) + .flatten(), + ); + let items = items.chain(self.modules.clean(cx).into_iter().flatten()); + let items = items.chain(self.proc_macros.iter().map(|hir_id| { let _def_id = hir_id.owner.local_def_index; // TODO: look how `rustc_metadata::rmeta::encoder` does this unimplemented!() @@ -320,7 +331,7 @@ impl Clean for hir::Crate<'_> { stability: cx.stability(id), deprecation: cx.deprecation(id).clean(cx), def_id: cx.tcx.hir().local_def_id(id).to_def_id(), - kind: ModuleItem(Module { is_crate: true, items }), + kind: ModuleItem(Module { is_crate: true, items: items.collect() }), } } } @@ -2226,45 +2237,40 @@ impl Clean> for doctree::Impl<'_> { } } -impl Clean> for doctree::ExternCrate<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - let please_inline = self.vis.node.is_pub() - && self.attrs.iter().any(|a| { - a.has_name(sym::doc) - && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, sym::inline), - None => false, - } - }); +fn clean_extern_crate( + item: &hir::Item<'_>, + renamed: Option, + cx: &DocContext<'_>, +) -> CleanedModule { + let please_inline = item.vis.node.is_pub() + && item.attrs.iter().any(|a| { + a.has_name(sym::doc) + && match a.meta_item_list() { + Some(l) => attr::list_contains_name(&l, sym::inline), + None => false, + } + }); + let def_id = cx.tcx.hir().local_def_id(item.hir_id).to_def_id(); + let name = cx.tcx.item_name(def_id); - if please_inline { - let mut visited = FxHashSet::default(); + if please_inline { + let mut visited = FxHashSet::default(); - let res = Res::Def(DefKind::Mod, DefId { krate: self.cnum, index: CRATE_DEF_INDEX }); + let res = Res::Def(DefKind::Mod, def_id); - if let Some(items) = inline::try_inline( - cx, - cx.tcx.parent_module(self.hir_id).to_def_id(), - res, - self.name, - Some(self.attrs), - &mut visited, - ) { - return items; - } + if let Some(items) = inline::try_inline( + cx, + cx.tcx.parent_module(item.hir_id).to_def_id(), + res, + name, + Some(item.attrs), + &mut visited, + ) { + return CleanedModule::Inlined(items); } - - vec![Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX }, - visibility: self.vis.clean(cx), - stability: None, - deprecation: None, - kind: ExternCrateItem(self.name.clean(cx), self.path.clone()), - }] } + + CleanedModule::Module(ExternCrateItem(name.clean(cx), renamed.clean(cx))) } impl Clean> for doctree::Import<'_> { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 93053704a16df..c0ae746abd197 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -7,8 +7,6 @@ use rustc_span::hygiene::MacroKind; use rustc_span::{self, Span, Symbol}; use rustc_hir as hir; -use rustc_hir::def_id::CrateNum; -use rustc_hir::HirId; #[derive(Debug, Clone, Copy)] crate enum StructType { @@ -125,17 +123,10 @@ crate struct Impl<'hir> { } crate struct ForeignItem<'hir> { + crate vis: &'hir hir::Visibility<'hir>, crate id: hir::HirId, crate name: Symbol, crate kind: &'hir hir::ForeignItemKind<'hir>, -} - -crate struct ExternCrate<'hir> { - crate name: Symbol, - crate hir_id: HirId, - crate cnum: CrateNum, - crate path: Option, - crate vis: &'hir hir::Visibility<'hir>, crate attrs: &'hir [ast::Attribute], crate span: Span, } From 4b2209783324a7ba36fe311ac3fe0b430274858e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 03:34:12 -0400 Subject: [PATCH 06/27] [WIP] fill out ImportItem --- src/librustdoc/clean/mod.rs | 205 ++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 112 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fc25a3624506c..e05205432a25a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -228,19 +228,10 @@ impl Clean for CrateNum { } } -/* -impl Clean for hir::ItemKind<'_> { - fn clean(&self, _cx: &DocContext<'_>) -> ItemEnum { - match self { - ExternalCrate(name) => - } - } -} -*/ - -enum CleanedModule { - Module(ItemKind), - Inlined(Vec), +enum MaybeInlined { + NotInlined(ItemKind), + InlinedWithoutOriginal(Vec), + InlinedWithOriginal(Vec, ItemKind), } impl Clean> for hir::Item<'_> { @@ -249,23 +240,14 @@ impl Clean> for hir::Item<'_> { let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); let name = cx.tcx.item_name(def_id).clean(cx); - let kind = match self.kind { + let maybe_inlined = match self.kind { // TODO: should store Symbol, not String - ItemKind::ExternCrate(renamed) => match clean_extern_crate(self, renamed, cx) { - CleanedModule::Module(inner) => inner, - CleanedModule::Inlined(items) => return items, - }, - ItemKind::Use(path, kind) => unimplemented!(), - /* - ImportItem(Import { - kind: kind.clean(cx), - source: path.clean(cx), - }), - */ + ItemKind::ExternCrate(renamed) => clean_extern_crate(self, renamed, cx), + ItemKind::Use(path, kind) => clean_import(self, path, kind, cx), _ => unimplemented!(), }; - vec![Item { + let build_item = |kind| Item { def_id, kind, name: Some(name), @@ -274,7 +256,17 @@ impl Clean> for hir::Item<'_> { visibility: self.vis.clean(cx), // TODO: use tcx.visibility once #78077 lands stability: cx.tcx.lookup_stability(def_id).copied(), deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx), - }] + }; + + match maybe_inlined { + MaybeInlined::NotInlined(inner) => vec![build_item(inner)], + MaybeInlined::InlinedWithoutOriginal(items) => items, + MaybeInlined::InlinedWithOriginal(mut items, inner) => { + let current = build_item(inner); + items.push(current); + items + } + } } } @@ -2241,7 +2233,7 @@ fn clean_extern_crate( item: &hir::Item<'_>, renamed: Option, cx: &DocContext<'_>, -) -> CleanedModule { +) -> MaybeInlined { let please_inline = item.vis.node.is_pub() && item.attrs.iter().any(|a| { a.has_name(sym::doc) @@ -2266,102 +2258,91 @@ fn clean_extern_crate( Some(item.attrs), &mut visited, ) { - return CleanedModule::Inlined(items); + return MaybeInlined::InlinedWithoutOriginal(items); } } - CleanedModule::Module(ExternCrateItem(name.clean(cx), renamed.clean(cx))) + MaybeInlined::NotInlined(ExternCrateItem(name.clean(cx), renamed.clean(cx))) } -impl Clean> for doctree::Import<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - // 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(); - } - - // 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() - || 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, +fn clean_import( + item: &hir::Item<'_>, + path: &hir::Path<'_>, + kind: hir::UseKind, + cx: &DocContext<'_>, +) -> MaybeInlined { + // 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 item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::StdImports) + // Ignore ListStem; rustdoc doesn't care about it + || kind == hir::UseKind::ListStem + { + return MaybeInlined::InlinedWithoutOriginal(Vec::new()); + } + + // 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 = !item.vis.node.is_pub() + || item.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 please_inline = self.attrs.lists(sym::doc).has_word(sym::inline); - 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 please_inline = item.attrs.lists(sym::doc).has_word(sym::inline); + let path = path.clean(cx); + let kind = 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 MaybeInlined::InlinedWithoutOriginal(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 { + let def_id = cx.tcx.hir().local_def_id(item.hir_id).to_def_id(); + let name = cx.tcx.item_name(def_id); + 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 let Some(mut items) = inline::try_inline( - cx, - cx.tcx.parent_module(self.id).to_def_id(), - path.res, - name, - Some(self.attrs), - &mut visited, - ) { - items.push(Item { - name: None, - attrs: 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), - stability: None, - deprecation: None, - kind: ImportItem(Import::new_simple( - self.name.clean(cx), - resolve_use_source(cx, path), - false, - )), - }); - return items; - } + } + if !denied { + let mut visited = FxHashSet::default(); + + if let Some(items) = inline::try_inline( + cx, + cx.tcx.parent_module(item.hir_id).to_def_id(), + path.res, + name, + Some(item.attrs), + &mut visited, + ) { + let kind = ImportItem(Import::new_simple( + name.clean(cx), + resolve_use_source(cx, path), + false, + )); + return MaybeInlined::InlinedWithOriginal(items, kind); } - Import::new_simple(name.clean(cx), resolve_use_source(cx, path), true) - }; + } + Import::new_simple(name.clean(cx), resolve_use_source(cx, path), true) + }; - vec![Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: DefId::local(CRATE_DEF_INDEX), - visibility: self.vis.clean(cx), - stability: None, - deprecation: None, - kind: ImportItem(inner), - }] - } + MaybeInlined::NotInlined(ImportItem(kind)) } impl Clean for doctree::ForeignItem<'_> { From 350e4d7ff8879cc519ef0f0bff001e80c816315a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 03:44:30 -0400 Subject: [PATCH 07/27] [WIP] add statics and unions --- src/librustdoc/clean/mod.rs | 103 +++++------------------------------- 1 file changed, 13 insertions(+), 90 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e05205432a25a..d8418eefc78a5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -237,6 +237,7 @@ enum MaybeInlined { impl Clean> for hir::Item<'_> { fn clean(&self, cx: &DocContext<'_>) -> Vec { use hir::ItemKind; + use MaybeInlined::NotInlined; let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); let name = cx.tcx.item_name(def_id).clean(cx); @@ -244,6 +245,18 @@ impl Clean> for hir::Item<'_> { // TODO: should store Symbol, not String ItemKind::ExternCrate(renamed) => clean_extern_crate(self, renamed, cx), ItemKind::Use(path, kind) => clean_import(self, path, kind, cx), + ItemKind::Static(ty, mutability, body_id) => NotInlined(StaticItem(Static { + type_: ty.clean(cx), + mutability, + expr: print_const_expr(cx, body_id), + })), + ItemKind::Const(ty, body_id) => unimplemented!(), + ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { + struct_type: doctree::struct_type_from_def(&variant_data), + generics: generics.clean(cx), + fields: variant_data.fields().clean(cx), + fields_stripped: false, + })), _ => unimplemented!(), }; @@ -334,64 +347,6 @@ impl Clean> for hir::ModuleItems { } } -/* -impl Clean for doctree::Module<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - // maintain a stack of mod ids, for doc comment path resolution - // but we also need to resolve the module's own docs based on whether its docs were written - // inside or outside the module, so check for that - let attrs = self.attrs.clean(cx); - - let mut items: Vec = vec![]; - items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx))); - items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); - items.extend(self.structs.iter().map(|x| x.clean(cx))); - items.extend(self.unions.iter().map(|x| x.clean(cx))); - items.extend(self.enums.iter().map(|x| x.clean(cx))); - items.extend(self.fns.iter().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.typedefs.iter().map(|x| x.clean(cx))); - items.extend(self.opaque_tys.iter().map(|x| x.clean(cx))); - items.extend(self.statics.iter().map(|x| x.clean(cx))); - items.extend(self.constants.iter().map(|x| x.clean(cx))); - items.extend(self.traits.iter().map(|x| x.clean(cx))); - items.extend(self.impls.iter().flat_map(|x| x.clean(cx))); - items.extend(self.macros.iter().map(|x| x.clean(cx))); - items.extend(self.proc_macros.iter().map(|x| x.clean(cx))); - items.extend(self.trait_aliases.iter().map(|x| x.clean(cx))); - - // determine if we should display the inner contents or - // the outer `mod` item for the source code. - let span = { - let sm = cx.sess().source_map(); - let outer = sm.lookup_char_pos(self.where_outer.lo()); - let inner = sm.lookup_char_pos(self.where_inner.lo()); - if outer.file.start_pos == inner.file.start_pos { - // mod foo { ... } - self.where_outer - } else { - // mod foo; (and a separate SourceFile for the contents) - self.where_inner - } - }; - - let what_rustc_thinks = Item::from_hir_id_and_parts( - self.id, - self.name, - ModuleItem(Module { is_crate: self.is_crate, items }), - cx, - ); - Item { - name: Some(what_rustc_thinks.name.unwrap_or_default()), - attrs, - source: span.clean(cx), - ..what_rustc_thinks - } - } -} -*/ - impl Clean for [ast::Attribute] { fn clean(&self, cx: &DocContext<'_>) -> Attributes { Attributes::from_ast(cx.sess().diagnostic(), self, None) @@ -1907,22 +1862,6 @@ impl Clean for doctree::Struct<'_> { } } -impl Clean for doctree::Union<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - UnionItem(Union { - struct_type: self.struct_type, - generics: self.generics.clean(cx), - fields: self.fields.clean(cx), - fields_stripped: false, - }), - cx, - ) - } -} - impl Clean for rustc_hir::VariantData<'_> { fn clean(&self, cx: &DocContext<'_>) -> VariantStruct { VariantStruct { @@ -2131,22 +2070,6 @@ impl Clean for hir::BareFnTy<'_> { } } -impl Clean for doctree::Static<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - debug!("cleaning static {}: {:?}", self.name.clean(cx), self); - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - StaticItem(Static { - type_: self.type_.clean(cx), - mutability: self.mutability, - expr: print_const_expr(cx, self.expr), - }), - cx, - ) - } -} - impl Clean for doctree::Constant<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let def_id = cx.tcx.hir().local_def_id(self.id).to_def_id(); From 5ba37bc2231591110aa0c4f3ca167a76d72c053a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 03:46:37 -0400 Subject: [PATCH 08/27] [WIP] add ConstantItem --- src/librustdoc/clean/mod.rs | 25 ++++++------------------- src/librustdoc/doctree.rs | 15 --------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d8418eefc78a5..bd13713d19b35 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -250,7 +250,12 @@ impl Clean> for hir::Item<'_> { mutability, expr: print_const_expr(cx, body_id), })), - ItemKind::Const(ty, body_id) => unimplemented!(), + ItemKind::Const(ty, body_id) => NotInlined(ConstantItem(Constant { + type_: ty.clean(cx), + expr: print_const_expr(cx, body_id), + value: print_evaluated_const(cx, def_id), + is_literal: is_literal_expr(cx, body_id.hir_id), + })), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -2070,24 +2075,6 @@ impl Clean for hir::BareFnTy<'_> { } } -impl Clean for doctree::Constant<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let def_id = cx.tcx.hir().local_def_id(self.id).to_def_id(); - - Item::from_def_id_and_parts( - def_id, - Some(self.name), - ConstantItem(Constant { - type_: self.type_.clean(cx), - expr: print_const_expr(cx, self.expr), - value: print_evaluated_const(cx, def_id), - is_literal: is_literal_expr(cx, self.expr.hir_id), - }), - cx, - ) - } -} - impl Clean for ty::ImplPolarity { fn clean(&self, _: &DocContext<'_>) -> ImplPolarity { match self { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index c0ae746abd197..e687a734551f3 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -26,14 +26,6 @@ crate struct Struct<'hir> { crate fields: &'hir [hir::StructField<'hir>], } -crate struct Union<'hir> { - crate id: hir::HirId, - crate struct_type: StructType, - crate name: Symbol, - crate generics: &'hir hir::Generics<'hir>, - crate fields: &'hir [hir::StructField<'hir>], -} - crate struct Enum<'hir> { crate variants: Vec>, crate generics: &'hir hir::Generics<'hir>, @@ -81,13 +73,6 @@ crate struct Static<'hir> { crate span: Span, } -crate struct Constant<'hir> { - crate type_: &'hir hir::Ty<'hir>, - crate expr: hir::BodyId, - crate name: Symbol, - crate id: hir::HirId, -} - crate struct Trait<'hir> { crate is_auto: hir::IsAuto, crate unsafety: hir::Unsafety, From bd38b65d97b471e32b311601429e0c72be92f8e3 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 03:55:47 -0400 Subject: [PATCH 09/27] [WIP] Add FunctionItem --- src/librustdoc/clean/mod.rs | 45 +++++++++++++++++-------------------- src/librustdoc/doctree.rs | 9 -------- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bd13713d19b35..adcd55a6aa074 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -256,6 +256,7 @@ impl Clean> for hir::Item<'_> { value: print_evaluated_const(cx, def_id), is_literal: is_literal_expr(cx, body_id.hir_id), })), + ItemKind::Fn(ref sig, ref generics, body) => NotInlined(clean_function(self, sig, &generics, body, cx)), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -962,32 +963,26 @@ impl<'a> Clean for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::Bo } } -impl Clean for doctree::Function<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let (generics, decl) = - enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx))); +fn clean_function(item: &hir::Item<'_>, sig: &hir::FnSig<'_>, generics: &hir::Generics<'_>, body: hir::BodyId, cx: &DocContext<'_>) -> ItemKind { + let (generics, decl) = + enter_impl_trait(cx, || (generics.clean(cx), (sig.decl, body).clean(cx))); - let did = cx.tcx.hir().local_def_id(self.id).to_def_id(); - let constness = if is_const_fn(cx.tcx, did) && !is_unstable_const_fn(cx.tcx, did).is_some() - { - hir::Constness::Const - } else { - hir::Constness::NotConst - }; - let (all_types, ret_types) = get_all_types(&generics, &decl, cx); - Item::from_def_id_and_parts( - did, - Some(self.name), - FunctionItem(Function { - decl, - generics, - header: hir::FnHeader { constness, ..self.header }, - all_types, - ret_types, - }), - cx, - ) - } + let did = cx.tcx.hir().local_def_id(item.hir_id); + let constness = if is_const_fn(cx.tcx, did.to_def_id()) + && !is_unstable_const_fn(cx.tcx, did.to_def_id()).is_some() + { + hir::Constness::Const + } else { + hir::Constness::NotConst + }; + let (all_types, ret_types) = get_all_types(&generics, &decl, cx); + FunctionItem(Function { + decl, + generics, + header: hir::FnHeader { constness, ..sig.header }, + all_types, + ret_types, + }) } impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index e687a734551f3..eaf18d7882fce 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -39,15 +39,6 @@ crate struct Variant<'hir> { crate def: &'hir hir::VariantData<'hir>, } -crate struct Function<'hir> { - crate decl: &'hir hir::FnDecl<'hir>, - crate id: hir::HirId, - crate name: Symbol, - crate header: hir::FnHeader, - crate generics: &'hir hir::Generics<'hir>, - crate body: hir::BodyId, -} - crate struct Typedef<'hir> { crate ty: &'hir hir::Ty<'hir>, crate gen: &'hir hir::Generics<'hir>, From 42d4dbbf35d3c353bca30f129934fb5e3c642f40 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:07:12 -0400 Subject: [PATCH 10/27] [WIP] ModuleItem --- src/librustdoc/clean/mod.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index adcd55a6aa074..d836842ab35e9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -256,7 +256,11 @@ impl Clean> for hir::Item<'_> { value: print_evaluated_const(cx, def_id), is_literal: is_literal_expr(cx, body_id.hir_id), })), - ItemKind::Fn(ref sig, ref generics, body) => NotInlined(clean_function(self, sig, &generics, body, cx)), + ItemKind::Fn(ref sig, ref generics, body) => { + NotInlined(clean_function(self, sig, &generics, body, cx)) + } + // TODO: this should also take the span into account (inner or outer) + ItemKind::Mod(ref mod_) => NotInlined(mod_.clean(cx)), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -347,6 +351,21 @@ impl Clean for hir::Crate<'_> { } } +impl Clean for hir::Mod<'_> { + fn clean(&self, cx: &DocContext<'_>) -> ItemKind { + ModuleItem(Module { + is_crate: false, + items: self.item_ids.clean(cx).into_iter().flatten().collect(), + }) + } +} + +impl Clean> for hir::ItemId { + fn clean(&self, cx: &DocContext<'_>) -> Vec { + cx.tcx.hir().item(self.id).clean(cx) + } +} + impl Clean> for hir::ModuleItems { fn clean(&self, _cx: &DocContext<'_>) -> Vec { unimplemented!() @@ -963,7 +982,13 @@ impl<'a> Clean for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::Bo } } -fn clean_function(item: &hir::Item<'_>, sig: &hir::FnSig<'_>, generics: &hir::Generics<'_>, body: hir::BodyId, cx: &DocContext<'_>) -> ItemKind { +fn clean_function( + item: &hir::Item<'_>, + sig: &hir::FnSig<'_>, + generics: &hir::Generics<'_>, + body: hir::BodyId, + cx: &DocContext<'_>, +) -> ItemKind { let (generics, decl) = enter_impl_trait(cx, || (generics.clean(cx), (sig.decl, body).clean(cx))); From a781126ea389ae0f3dcb13042095f5c8f7d2cacf Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:14:53 -0400 Subject: [PATCH 11/27] ForeignItem --- src/librustdoc/clean/mod.rs | 21 +++++++++++++-------- src/librustdoc/doctree.rs | 9 --------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d836842ab35e9..3804133da6302 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -261,6 +261,7 @@ impl Clean> for hir::Item<'_> { } // TODO: this should also take the span into account (inner or outer) ItemKind::Mod(ref mod_) => NotInlined(mod_.clean(cx)), + ItemKind::ForeignMod(ref mod_) => NotInlined(mod_.clean(cx)), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -360,6 +361,12 @@ impl Clean for hir::Mod<'_> { } } +impl Clean for hir::ForeignMod<'_> { + fn clean(&self, cx: &DocContext<'_>) -> ItemKind { + ModuleItem(Module { is_crate: false, items: self.items.clean(cx) }) + } +} + impl Clean> for hir::ItemId { fn clean(&self, cx: &DocContext<'_>) -> Vec { cx.tcx.hir().item(self.id).clean(cx) @@ -2275,11 +2282,11 @@ fn clean_import( MaybeInlined::NotInlined(ImportItem(kind)) } -impl Clean for doctree::ForeignItem<'_> { +impl Clean for hir::ForeignItem<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let kind = match self.kind { hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => { - let abi = cx.tcx.hir().get_foreign_abi(self.id); + let abi = cx.tcx.hir().get_foreign_abi(self.hir_id); let (generics, decl) = enter_impl_trait(cx, || (generics.clean(cx), (&**decl, &names[..]).clean(cx))); let (all_types, ret_types) = get_all_types(&generics, &decl, cx); @@ -2296,15 +2303,13 @@ impl Clean for doctree::ForeignItem<'_> { ret_types, }) } - hir::ForeignItemKind::Static(ref ty, mutbl) => ForeignStaticItem(Static { - type_: ty.clean(cx), - mutability: *mutbl, - expr: String::new(), - }), + hir::ForeignItemKind::Static(ref ty, mutability) => { + ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: String::new() }) + } hir::ForeignItemKind::Type => ForeignTypeItem, }; - Item::from_hir_id_and_parts(self.id, Some(self.name), kind, cx) + Item::from_hir_id_and_parts(self.hir_id, Some(self.ident.name), kind, cx) } } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index eaf18d7882fce..92df9d937f361 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -98,15 +98,6 @@ crate struct Impl<'hir> { crate id: hir::HirId, } -crate struct ForeignItem<'hir> { - crate vis: &'hir hir::Visibility<'hir>, - crate id: hir::HirId, - crate name: Symbol, - crate kind: &'hir hir::ForeignItemKind<'hir>, - crate attrs: &'hir [ast::Attribute], - crate span: Span, -} - #[derive(Debug)] crate struct Import<'hir> { crate name: Symbol, From 1589dda3f7f43b70dc767e0d0169483d6e9eb307 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:20:36 -0400 Subject: [PATCH 12/27] GlobalAsm and TypedefItem --- src/librustdoc/clean/mod.rs | 22 +++++++++------------- src/librustdoc/doctree.rs | 7 ------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3804133da6302..d1792f04e70a3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -262,6 +262,15 @@ impl Clean> for hir::Item<'_> { // TODO: this should also take the span into account (inner or outer) ItemKind::Mod(ref mod_) => NotInlined(mod_.clean(cx)), ItemKind::ForeignMod(ref mod_) => NotInlined(mod_.clean(cx)), + ItemKind::GlobalAsm(..) => MaybeInlined::InlinedWithoutOriginal(vec![]), // not handled + ItemKind::TyAlias(ty, ref generics) => { + let rustdoc_ty = ty.clean(cx); + let item_type = rustdoc_ty.def_id().and_then(|did| inline::build_ty(cx, did)); + NotInlined(TypedefItem( + Typedef { type_: rustdoc_ty, generics: generics.clean(cx), item_type }, + false, + )) + } ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -2066,19 +2075,6 @@ impl Clean for Symbol { } } -impl Clean for doctree::Typedef<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let type_ = self.ty.clean(cx); - let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), - cx, - ) - } -} - impl Clean for doctree::OpaqueTy<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item::from_hir_id_and_parts( diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 92df9d937f361..ce37465cff6e8 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -39,13 +39,6 @@ crate struct Variant<'hir> { crate def: &'hir hir::VariantData<'hir>, } -crate struct Typedef<'hir> { - crate ty: &'hir hir::Ty<'hir>, - crate gen: &'hir hir::Generics<'hir>, - crate name: Symbol, - crate id: hir::HirId, -} - crate struct OpaqueTy<'hir> { crate opaque_ty: &'hir hir::OpaqueTy<'hir>, crate name: Symbol, From f4e389699dc5ffb075d59945199d491fb7ca16ef Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:23:20 -0400 Subject: [PATCH 13/27] OpaqueTy --- src/librustdoc/clean/mod.rs | 18 ++++-------------- src/librustdoc/doctree.rs | 6 ------ 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d1792f04e70a3..497cbb807c687 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -271,6 +271,10 @@ impl Clean> for hir::Item<'_> { false, )) } + ItemKind::OpaqueTy(ref ty) => NotInlined(OpaqueTyItem(OpaqueTy { + bounds: ty.bounds.clean(cx), + generics: ty.generics.clean(cx), + })), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -2075,20 +2079,6 @@ impl Clean for Symbol { } } -impl Clean for doctree::OpaqueTy<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - OpaqueTyItem(OpaqueTy { - bounds: self.opaque_ty.bounds.clean(cx), - generics: self.opaque_ty.generics.clean(cx), - }), - cx, - ) - } -} - impl Clean for hir::BareFnTy<'_> { fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, || { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index ce37465cff6e8..bbb64b1f870ef 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -39,12 +39,6 @@ crate struct Variant<'hir> { crate def: &'hir hir::VariantData<'hir>, } -crate struct OpaqueTy<'hir> { - crate opaque_ty: &'hir hir::OpaqueTy<'hir>, - crate name: Symbol, - crate id: hir::HirId, -} - #[derive(Debug)] crate struct Static<'hir> { crate type_: &'hir hir::Ty<'hir>, From 0a1507d60779c82aa041a84d1cc2218c101655db Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:29:30 -0400 Subject: [PATCH 14/27] Enum and Variant --- src/librustdoc/clean/mod.rs | 32 ++++++++------------------------ src/librustdoc/doctree.rs | 13 ------------- 2 files changed, 8 insertions(+), 37 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 497cbb807c687..15b61ae2bd45c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -275,6 +275,11 @@ impl Clean> for hir::Item<'_> { bounds: ty.bounds.clean(cx), generics: ty.generics.clean(cx), })), + ItemKind::Enum(ref def, ref generics) => NotInlined(EnumItem(Enum { + variants: def.variants.iter().map(|v| v.clean(cx)).collect(), + generics: generics.clean(cx), + variants_stripped: false, + })), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -1917,31 +1922,10 @@ impl Clean for rustc_hir::VariantData<'_> { } } -impl Clean for doctree::Enum<'_> { +impl Clean for hir::Variant<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - EnumItem(Enum { - variants: self.variants.iter().map(|v| v.clean(cx)).collect(), - generics: self.generics.clean(cx), - variants_stripped: false, - }), - cx, - ) - } -} - -impl Clean for doctree::Variant<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let what_rustc_thinks = Item::from_hir_id_and_parts( - self.id, - Some(self.name), - VariantItem(Variant { kind: self.def.clean(cx) }), - cx, - ); - // don't show `pub` for variants, which are always public - Item { visibility: Inherited, ..what_rustc_thinks } + let kind = VariantItem(Variant { kind: self.data.clean(cx) }); + Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx) } } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index bbb64b1f870ef..51b9b962a296a 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -26,19 +26,6 @@ crate struct Struct<'hir> { crate fields: &'hir [hir::StructField<'hir>], } -crate struct Enum<'hir> { - crate variants: Vec>, - crate generics: &'hir hir::Generics<'hir>, - crate id: hir::HirId, - crate name: Symbol, -} - -crate struct Variant<'hir> { - crate name: Symbol, - crate id: hir::HirId, - crate def: &'hir hir::VariantData<'hir>, -} - #[derive(Debug)] crate struct Static<'hir> { crate type_: &'hir hir::Ty<'hir>, From 04de151805b8ec5eed6102438e41de7cf3477fad Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:32:01 -0400 Subject: [PATCH 15/27] Struct --- src/librustdoc/clean/mod.rs | 22 ++++++---------------- src/librustdoc/doctree.rs | 8 -------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 15b61ae2bd45c..5c604dc134210 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -280,6 +280,12 @@ impl Clean> for hir::Item<'_> { generics: generics.clean(cx), variants_stripped: false, })), + ItemKind::Struct(ref variant_data, ref generics) => NotInlined(StructItem(Struct { + struct_type: doctree::struct_type_from_def(&variant_data), + generics: generics.clean(cx), + fields: variant_data.fields().clean(cx), + fields_stripped: false, + })), ItemKind::Union(ref variant_data, ref generics) => NotInlined(UnionItem(Union { struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), @@ -1896,22 +1902,6 @@ impl Clean for ty::Visibility { } } -impl Clean for doctree::Struct<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - StructItem(Struct { - struct_type: self.struct_type, - generics: self.generics.clean(cx), - fields: self.fields.clean(cx), - fields_stripped: false, - }), - cx, - ) - } -} - impl Clean for rustc_hir::VariantData<'_> { fn clean(&self, cx: &DocContext<'_>) -> VariantStruct { VariantStruct { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 51b9b962a296a..8f19f5fd67d1a 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -18,14 +18,6 @@ crate enum StructType { Unit, } -crate struct Struct<'hir> { - crate id: hir::HirId, - crate struct_type: StructType, - crate name: Symbol, - crate generics: &'hir hir::Generics<'hir>, - crate fields: &'hir [hir::StructField<'hir>], -} - #[derive(Debug)] crate struct Static<'hir> { crate type_: &'hir hir::Ty<'hir>, From d0302f6e740c1672bf7d6ad527ae75f9b034688d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:37:49 -0400 Subject: [PATCH 16/27] Trait --- src/librustdoc/clean/mod.rs | 37 +++++++++++++++++-------------------- src/librustdoc/doctree.rs | 11 ----------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5c604dc134210..1957ec98b1d2c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -292,6 +292,23 @@ impl Clean> for hir::Item<'_> { fields: variant_data.fields().clean(cx), fields_stripped: false, })), + ItemKind::Trait(is_auto, unsafety, ref generics, bounds, item_ids) => { + let attrs = self.attrs.clean(cx); + let is_spotlight = attrs.has_doc_flag(sym::spotlight); + NotInlined(TraitItem(Trait { + auto: is_auto.clean(cx), + unsafety, + items: item_ids + .iter() + .map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)) + .collect(), + generics: generics.clean(cx), + bounds: bounds.clean(cx), + is_spotlight, + // TODO: this is redundant with `auto` + is_auto: is_auto.clean(cx), + })) + } _ => unimplemented!(), }; @@ -1125,26 +1142,6 @@ impl Clean for hir::FnRetTy<'_> { } } -impl Clean for doctree::Trait<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let attrs = self.attrs.clean(cx); - let is_spotlight = attrs.has_doc_flag(sym::spotlight); - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - TraitItem(Trait { - unsafety: self.unsafety, - items: self.items.iter().map(|ti| ti.clean(cx)).collect(), - generics: self.generics.clean(cx), - bounds: self.bounds.clean(cx), - is_spotlight, - is_auto: self.is_auto.clean(cx), - }), - cx, - ) - } -} - impl Clean for doctree::TraitAlias<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item::from_hir_id_and_parts( diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 8f19f5fd67d1a..8b4aa94849bd3 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -30,17 +30,6 @@ crate struct Static<'hir> { crate span: Span, } -crate struct Trait<'hir> { - crate is_auto: hir::IsAuto, - crate unsafety: hir::Unsafety, - crate name: Symbol, - crate items: Vec<&'hir hir::TraitItem<'hir>>, - crate generics: &'hir hir::Generics<'hir>, - crate bounds: &'hir [hir::GenericBound<'hir>], - crate attrs: &'hir [ast::Attribute], - crate id: hir::HirId, -} - crate struct TraitAlias<'hir> { crate name: Symbol, crate generics: &'hir hir::Generics<'hir>, From 0d7c1463918642116c031906e253081d3823261d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:40:09 -0400 Subject: [PATCH 17/27] TraitAlias --- src/librustdoc/clean/mod.rs | 18 ++++-------------- src/librustdoc/doctree.rs | 7 ------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1957ec98b1d2c..a1adde7030983 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -309,6 +309,10 @@ impl Clean> for hir::Item<'_> { is_auto: is_auto.clean(cx), })) } + ItemKind::TraitAlias(ref generics, bounds) => NotInlined(TraitAliasItem(TraitAlias { + generics: generics.clean(cx), + bounds: bounds.clean(cx), + })), _ => unimplemented!(), }; @@ -1142,20 +1146,6 @@ impl Clean for hir::FnRetTy<'_> { } } -impl Clean for doctree::TraitAlias<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item::from_hir_id_and_parts( - self.id, - Some(self.name), - TraitAliasItem(TraitAlias { - generics: self.generics.clean(cx), - bounds: self.bounds.clean(cx), - }), - cx, - ) - } -} - impl Clean for hir::IsAuto { fn clean(&self, _: &DocContext<'_>) -> bool { match *self { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 8b4aa94849bd3..213d927916f16 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -30,13 +30,6 @@ crate struct Static<'hir> { crate span: Span, } -crate struct TraitAlias<'hir> { - crate name: Symbol, - crate generics: &'hir hir::Generics<'hir>, - crate bounds: &'hir [hir::GenericBound<'hir>], - crate id: hir::HirId, -} - #[derive(Debug)] crate struct Impl<'hir> { crate unsafety: hir::Unsafety, From d0f7ce9c7d3d60598777042b1922c91bec9be6f6 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 04:57:46 -0400 Subject: [PATCH 18/27] Impl --- src/librustdoc/clean/mod.rs | 107 +++++++++++++++++++----------------- src/librustdoc/doctree.rs | 16 ------ 2 files changed, 58 insertions(+), 65 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a1adde7030983..ecd386a2a98ea 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -313,7 +313,7 @@ impl Clean> for hir::Item<'_> { generics: generics.clean(cx), bounds: bounds.clean(cx), })), - _ => unimplemented!(), + ItemKind::Impl { .. } => return clean_impl(self, cx), }; let build_item = |kind| Item { @@ -2060,57 +2060,66 @@ impl Clean for ty::ImplPolarity { } } -impl Clean> for doctree::Impl<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - let mut ret = Vec::new(); - let trait_ = self.trait_.clean(cx); - let items = self.items.iter().map(|ii| ii.clean(cx)).collect::>(); - let def_id = cx.tcx.hir().local_def_id(self.id); - - // If this impl block is an implementation of the Deref trait, then we - // need to try inlining the target's inherent impl blocks as well. - if trait_.def_id() == cx.tcx.lang_items().deref_trait() { - build_deref_target_impls(cx, &items, &mut ret); +fn clean_impl(item: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec { + let (unsafety, of_trait, self_ty, items, generics) = match item.kind { + hir::ItemKind::Impl { unsafety, ref of_trait, self_ty, items, ref generics, .. } => { + (unsafety, of_trait, self_ty, items, generics) } + _ => unreachable!(), + }; - let provided: FxHashSet = trait_ - .def_id() - .map(|did| { - cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect() - }) - .unwrap_or_default(); - - let for_ = self.for_.clean(cx); - let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) { - DefKind::TyAlias => Some(cx.tcx.type_of(did).clean(cx)), - _ => None, - }); - let make_item = |trait_: Option, for_: Type, items: Vec| Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: def_id.to_def_id(), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id), - deprecation: cx.deprecation(self.id).clean(cx), - kind: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided.clone(), - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - }; - if let Some(type_alias) = type_alias { - ret.push(make_item(trait_.clone(), type_alias, items.clone())); - } - ret.push(make_item(trait_, for_, items)); - ret + // Don't duplicate impls when implementing a trait, we'll pick + // them up regardless of where they're located. + if of_trait.is_some() { + return vec![]; + } + + let mut ret = Vec::new(); + let trait_ = of_trait.clean(cx); + let items: Vec<_> = items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect(); + let def_id = cx.tcx.hir().local_def_id(item.hir_id); + + // If this impl block is an implementation of the Deref trait, then we + // need to try inlining the target's inherent impl blocks as well. + if trait_.def_id() == cx.tcx.lang_items().deref_trait() { + build_deref_target_impls(cx, &items, &mut ret); + } + + let provided: FxHashSet = trait_ + .def_id() + .map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect()) + .unwrap_or_default(); + + let for_ = self_ty.clean(cx); + let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) { + DefKind::TyAlias => Some(cx.tcx.type_of(did).clean(cx)), + _ => None, + }); + let make_item = |trait_: Option, for_: Type, items: Vec| Item { + name: None, + attrs: item.attrs.clean(cx), + source: item.span.clean(cx), + def_id: def_id.to_def_id(), + visibility: item.vis.clean(cx), + stability: cx.stability(item.hir_id), + deprecation: cx.deprecation(item.hir_id).clean(cx), + kind: ImplItem(Impl { + unsafety, + generics: generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_, + for_, + items, + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), + }; + if let Some(type_alias) = type_alias { + ret.push(make_item(trait_.clone(), type_alias, items.clone())); } + ret.push(make_item(trait_, for_, items)); + ret } fn clean_extern_crate( diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 213d927916f16..f71ea805e1f99 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -30,22 +30,6 @@ crate struct Static<'hir> { crate span: Span, } -#[derive(Debug)] -crate struct Impl<'hir> { - crate unsafety: hir::Unsafety, - crate polarity: hir::ImplPolarity, - crate defaultness: hir::Defaultness, - crate constness: hir::Constness, - crate generics: &'hir hir::Generics<'hir>, - crate trait_: &'hir Option>, - crate for_: &'hir hir::Ty<'hir>, - crate items: Vec<&'hir hir::ImplItem<'hir>>, - crate attrs: &'hir [ast::Attribute], - crate span: Span, - crate vis: &'hir hir::Visibility<'hir>, - crate id: hir::HirId, -} - #[derive(Debug)] crate struct Import<'hir> { crate name: Symbol, From ed27f87c11cde33a365a6d2b6c0064d50b41f1d4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 05:10:18 -0400 Subject: [PATCH 19/27] ModuleItems --- src/librustdoc/clean/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ecd386a2a98ea..eb7af5810a7de 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -347,6 +347,7 @@ impl Clean for hir::Crate<'_> { // Get _all_ the items! let items = self.items.clean(cx).into_iter().flatten(); + let items = items.chain(self.item.module.item_ids.clean(cx).into_iter().flatten()); let items = items.chain(self.exported_macros.clean(cx)); let items = items.chain(self.trait_items.clean(cx)); let items = items.chain(self.impl_items.clean(cx)); @@ -360,7 +361,6 @@ impl Clean for hir::Crate<'_> { }) .flatten(), ); - let items = items.chain(self.modules.clean(cx).into_iter().flatten()); let items = items.chain(self.proc_macros.iter().map(|hir_id| { let _def_id = hir_id.owner.local_def_index; // TODO: look how `rustc_metadata::rmeta::encoder` does this @@ -418,12 +418,6 @@ impl Clean> for hir::ItemId { } } -impl Clean> for hir::ModuleItems { - fn clean(&self, _cx: &DocContext<'_>) -> Vec { - unimplemented!() - } -} - impl Clean for [ast::Attribute] { fn clean(&self, cx: &DocContext<'_>) -> Attributes { Attributes::from_ast(cx.sess().diagnostic(), self, None) From 1697adaa1a275fc8c9f5c37b3b8d37da2bbf3128 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 05:12:19 -0400 Subject: [PATCH 20/27] Add crate name --- src/librustdoc/clean/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index eb7af5810a7de..4e2e2473ef2cf 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -341,8 +341,6 @@ impl Clean> for hir::Item<'_> { impl Clean for hir::Crate<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { - // TODO: use tcx.crate_name instead - let name = None; let attrs = self.item.attrs.clean(cx); // Get _all_ the items! @@ -385,7 +383,7 @@ impl Clean for hir::Crate<'_> { let id = hir::CRATE_HIR_ID; Item { - name, + name: Some(cx.tcx.crate_name.clean(cx)), attrs, source: span.clean(cx), visibility: Visibility::Public, From 44cef3e16af28df85df4fdd7546eede7c349a70a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 05:13:52 -0400 Subject: [PATCH 21/27] Cleanup some TODOs --- src/librustdoc/clean/mod.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4e2e2473ef2cf..5518c56ae76ab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -242,7 +242,6 @@ impl Clean> for hir::Item<'_> { let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); let name = cx.tcx.item_name(def_id).clean(cx); let maybe_inlined = match self.kind { - // TODO: should store Symbol, not String ItemKind::ExternCrate(renamed) => clean_extern_crate(self, renamed, cx), ItemKind::Use(path, kind) => clean_import(self, path, kind, cx), ItemKind::Static(ty, mutability, body_id) => NotInlined(StaticItem(Static { @@ -305,7 +304,7 @@ impl Clean> for hir::Item<'_> { generics: generics.clean(cx), bounds: bounds.clean(cx), is_spotlight, - // TODO: this is redundant with `auto` + // FIXME: this is redundant with `auto` is_auto: is_auto.clean(cx), })) } @@ -321,8 +320,8 @@ impl Clean> for hir::Item<'_> { kind, name: Some(name), source: cx.tcx.def_span(def_id).clean(cx), - attrs: self.attrs.clean(cx), // should this use tcx.attrs instead? - visibility: self.vis.clean(cx), // TODO: use tcx.visibility once #78077 lands + attrs: self.attrs.clean(cx), // TODO: should this use tcx.attrs instead? + visibility: self.vis.clean(cx), // TODO: should this use tcx.visibility instead? stability: cx.tcx.lookup_stability(def_id).copied(), deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx), }; @@ -2268,7 +2267,7 @@ impl Clean for hir::MacroDef<'_> { let matchers = tts.chunks(4).map(|arm| arm[0].span()); Item { - name: Some(self.ident.name.to_string()), // TODO: this should store a Symbol + name: Some(self.ident.name.to_string()), attrs: self.attrs.clean(cx), source: self.span.clean(cx), visibility: Public, From a79eb206cb1f6b821f442b98488768a520bc67b9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 16 Nov 2020 22:38:44 -0500 Subject: [PATCH 22/27] Fix crash on items only named in HIR --- src/librustdoc/clean/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5518c56ae76ab..b7de3d40078a3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -240,7 +240,7 @@ impl Clean> for hir::Item<'_> { use MaybeInlined::NotInlined; let def_id = cx.tcx.hir().local_def_id(self.hir_id).to_def_id(); - let name = cx.tcx.item_name(def_id).clean(cx); + let name = cx.tcx.hir().name(self.hir_id); let maybe_inlined = match self.kind { ItemKind::ExternCrate(renamed) => clean_extern_crate(self, renamed, cx), ItemKind::Use(path, kind) => clean_import(self, path, kind, cx), @@ -318,7 +318,7 @@ impl Clean> for hir::Item<'_> { let build_item = |kind| Item { def_id, kind, - name: Some(name), + name: Some(name.to_string()), source: cx.tcx.def_span(def_id).clean(cx), attrs: self.attrs.clean(cx), // TODO: should this use tcx.attrs instead? visibility: self.vis.clean(cx), // TODO: should this use tcx.visibility instead? @@ -2193,8 +2193,7 @@ fn clean_import( } Import::new_glob(resolve_use_source(cx, path), true) } else { - let def_id = cx.tcx.hir().local_def_id(item.hir_id).to_def_id(); - let name = cx.tcx.item_name(def_id); + let name = cx.tcx.hir().name(item.hir_id); if !please_inline { if let Res::Def(DefKind::Mod, did) = path.res { if !did.is_local() && did.index == CRATE_DEF_INDEX { From ba301acc6babaea05579e949bad20e5bf61b539c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 16 Nov 2020 23:53:40 -0500 Subject: [PATCH 23/27] Don't ICE on trait functions and imports It turns out these were being silently dropped before because they didn't have a name. --- src/librustdoc/formats/renderer.rs | 5 ++++- src/librustdoc/html/render/mod.rs | 16 ++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index d0fdc69cc1932..6e0a2812f8f4f 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -97,7 +97,10 @@ crate fn run_format( cx.mod_item_out(&name)?; } else if item.name.is_some() { - cx.item(item, &cache)?; + match item.kind { + clean::ItemKind::ImportItem(..) => {} + _ => cx.item(item, &cache)?, + } } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 28f7a4d316248..3061f98c073d7 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1725,7 +1725,10 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) "Module " } } - clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => "Function ", + clean::FunctionItem(..) + | clean::ForeignFunctionItem(..) + | clean::TyMethodItem(..) + | clean::MethodItem(..) => "Function ", clean::TraitItem(..) => "Trait ", clean::StructItem(..) => "Struct ", clean::UnionItem(..) => "Union ", @@ -1746,7 +1749,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) clean::TraitAliasItem(..) => "Trait Alias ", _ => { // We don't generate pages for any other type. - unreachable!(); + unreachable!("unknown kind {:?}", item.kind); } }; buf.write_str(name); @@ -1768,9 +1771,10 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) match item.kind { clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items), - clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => { - item_function(buf, cx, item, f) - } + clean::FunctionItem(ref f) + | clean::ForeignFunctionItem(ref f) + | clean::TyMethodItem(ref f) + | clean::MethodItem(ref f, _) => item_function(buf, cx, item, f), clean::TraitItem(ref t) => item_trait(buf, cx, item, t, cache), clean::StructItem(ref s) => item_struct(buf, cx, item, s, cache), clean::UnionItem(ref s) => item_union(buf, cx, item, s, cache), @@ -1787,7 +1791,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) clean::TraitAliasItem(ref ta) => item_trait_alias(buf, cx, item, ta, cache), _ => { // We don't generate pages for any other type. - unreachable!(); + unreachable!("unknown kind {:?}", item.kind); } } } From ee0cad5bafe0bafc3376acc47df01ac44e608322 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 17 Nov 2020 00:21:36 -0500 Subject: [PATCH 24/27] Fix broken handling of extern "ABI" blocks ForeignModule is just such a terrible name for these. --- src/librustdoc/clean/mod.rs | 9 +++++---- src/librustdoc/formats/renderer.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b7de3d40078a3..67eb68c832500 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -260,7 +260,8 @@ impl Clean> for hir::Item<'_> { } // TODO: this should also take the span into account (inner or outer) ItemKind::Mod(ref mod_) => NotInlined(mod_.clean(cx)), - ItemKind::ForeignMod(ref mod_) => NotInlined(mod_.clean(cx)), + // `extern "C" { ... }` + ItemKind::ForeignMod(ref mod_) => MaybeInlined::InlinedWithoutOriginal(mod_.clean(cx)), ItemKind::GlobalAsm(..) => MaybeInlined::InlinedWithoutOriginal(vec![]), // not handled ItemKind::TyAlias(ty, ref generics) => { let rustdoc_ty = ty.clean(cx); @@ -403,9 +404,9 @@ impl Clean for hir::Mod<'_> { } } -impl Clean for hir::ForeignMod<'_> { - fn clean(&self, cx: &DocContext<'_>) -> ItemKind { - ModuleItem(Module { is_crate: false, items: self.items.clean(cx) }) +impl Clean> for hir::ForeignMod<'_> { + fn clean(&self, cx: &DocContext<'_>) -> Vec { + self.items.iter().map(|x| x.clean(cx)).collect() } } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 6e0a2812f8f4f..fb0b41984af10 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -82,7 +82,7 @@ crate fn run_format( // recurse into the items of the module as well. let name = item.name.as_ref().unwrap().to_string(); if name.is_empty() { - panic!("Unexpected module with empty name"); + panic!("Unexpected module with empty name: {:?}", item); } cx.mod_item_in(&item, &name, &cache)?; From e27b769f0ae9fe2ffee97615985c5bf5c3f3c8d3 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 18 Nov 2020 12:19:39 -0500 Subject: [PATCH 25/27] debugging --- src/librustdoc/formats/cache.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 917c1a95fdbf5..4e01e2824a4cf 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -269,7 +269,8 @@ impl DocFolder for Cache { | clean::StructFieldItem(..) | clean::VariantItem(..) => ( ( - Some(*self.parent_stack.last().expect("parent_stack is empty")), + Some(*self.parent_stack.last() + .unwrap_or_else(|| panic!("parent_stack is empty (while indexing {:?})", item.kind))), Some(&self.stack[..self.stack.len() - 1]), ), false, @@ -303,7 +304,7 @@ impl DocFolder for Cache { match parent { (parent, Some(path)) if is_inherent_impl_item || !self.stripped_mod => { - debug_assert!(!item.is_stripped()); + debug_assert!(!item.is_stripped(), "name={:?}, kind={:?}", item.name, item.kind); // A crate has a module at its root, containing all items, // which should not be indexed. The crate-item itself is From 9eaca9d046c7edd876120f841198408ce11d99e2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 18 Nov 2020 17:23:19 -0500 Subject: [PATCH 26/27] Fix semantic conflict --- src/librustdoc/clean/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 67eb68c832500..290668a23786f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -296,7 +296,6 @@ impl Clean> for hir::Item<'_> { let attrs = self.attrs.clean(cx); let is_spotlight = attrs.has_doc_flag(sym::spotlight); NotInlined(TraitItem(Trait { - auto: is_auto.clean(cx), unsafety, items: item_ids .iter() From 5e2793beb3bf4d760cf29eeb15f6d903a2b46a91 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 18 Nov 2020 18:10:47 -0500 Subject: [PATCH 27/27] Small cleanups - Add back call to `from_hir_id_and_parts()` - Remove outdated comment --- src/librustdoc/clean/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 290668a23786f..c6291587c1b84 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -304,7 +304,6 @@ impl Clean> for hir::Item<'_> { generics: generics.clean(cx), bounds: bounds.clean(cx), is_spotlight, - // FIXME: this is redundant with `auto` is_auto: is_auto.clean(cx), })) } @@ -380,16 +379,17 @@ impl Clean for hir::Crate<'_> { } }; - let id = hir::CRATE_HIR_ID; + let what_rustc_thinks = Item::from_hir_id_and_parts( + hir::CRATE_HIR_ID, + Some(cx.tcx.crate_name), + ModuleItem(Module { is_crate: true, items: items.collect() }), + cx, + ); Item { - name: Some(cx.tcx.crate_name.clean(cx)), + name: Some(what_rustc_thinks.name.unwrap_or_default()), attrs, source: span.clean(cx), - visibility: Visibility::Public, - stability: cx.stability(id), - deprecation: cx.deprecation(id).clean(cx), - def_id: cx.tcx.hir().local_def_id(id).to_def_id(), - kind: ModuleItem(Module { is_crate: true, items: items.collect() }), + ..what_rustc_thinks } } }