From f879ecc4ef62b5c434e85a9db845b6c1020162ca Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Mar 2021 16:04:24 +0100 Subject: [PATCH 1/2] Make ItemKind::ExternCrate looks like hir::ItemKind::ExternCrate to make transition over hir::ItemKind simpler --- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/clean/types.rs | 7 ++- src/librustdoc/formats/item_type.rs | 2 +- src/librustdoc/formats/renderer.rs | 4 +- src/librustdoc/html/render/print_item.rs | 6 +- src/librustdoc/json/conversions.rs | 62 ++++++++++--------- src/librustdoc/json/mod.rs | 2 +- .../passes/calculate_doc_coverage.rs | 2 +- src/librustdoc/passes/doc_test_lints.rs | 2 +- src/librustdoc/passes/stripper.rs | 6 +- 10 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5d81498f8d210..29eb67f023f0b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2129,12 +2129,12 @@ fn clean_extern_crate( } // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason vec![Item { - name: None, + name: Some(name), attrs: box krate.attrs.clean(cx), source: krate.span.clean(cx), def_id: crate_def_id, visibility: krate.vis.clean(cx), - kind: box ExternCrateItem(name, orig_name), + kind: box ExternCrateItem { src: orig_name }, }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index e3f47a85d5154..e560843383ec5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -323,7 +323,10 @@ impl Item { #[derive(Clone, Debug)] crate enum ItemKind { - ExternCrateItem(Symbol, Option), + ExternCrateItem { + /// The crate's name, *not* the name it's imported as. + src: Option, + }, ImportItem(Import), StructItem(Struct), UnionItem(Union), @@ -376,7 +379,7 @@ impl ItemKind { TraitItem(t) => t.items.iter(), ImplItem(i) => i.items.iter(), ModuleItem(m) => m.items.iter(), - ExternCrateItem(_, _) + ExternCrateItem { .. } | ImportItem(_) | FunctionItem(_) | TypedefItem(_, _) diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 7922a1ffa062e..460d4b907c09a 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -67,7 +67,7 @@ impl<'a> From<&'a clean::Item> for ItemType { match *kind { clean::ModuleItem(..) => ItemType::Module, - clean::ExternCrateItem(..) => ItemType::ExternCrate, + clean::ExternCrateItem { .. } => ItemType::ExternCrate, clean::ImportItem(..) => ItemType::Import, clean::StructItem(..) => ItemType::Struct, clean::UnionItem(..) => ItemType::Union, diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index b779363e5c701..0487da1e7d020 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -91,7 +91,9 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( } cx.mod_item_out(&name)?; - } else if item.name.is_some() { + // FIXME: checking `item.name.is_some()` is very implicit and leads to lots of special + // cases. Use an explicit match instead. + } else if item.name.is_some() && !item.is_extern_crate() { prof.generic_activity_with_arg("render_item", &*item.name.unwrap_or(unknown).as_str()) .run(|| cx.item(item))?; } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6d61248f28ef0..6cdd3838023e6 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -240,7 +240,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl } match *myitem.kind { - clean::ExternCrateItem(ref name, ref src) => { + clean::ExternCrateItem { ref src } => { use crate::html::format::anchor; match *src { @@ -249,13 +249,13 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl "{}extern crate {} as {};", myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()), anchor(myitem.def_id, &*src.as_str(), cx.cache()), - name + myitem.name.as_ref().unwrap(), ), None => write!( w, "{}extern crate {};", myitem.visibility.print_with_space(cx.tcx(), myitem.def_id, cx.cache()), - anchor(myitem.def_id, &*name.as_str(), cx.cache()) + anchor(myitem.def_id, &*myitem.name.as_ref().unwrap().as_str(), cx.cache()), ), } w.write_str(""); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index da09d49a0066a..a579b66134531 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -10,6 +10,7 @@ use rustc_ast::ast; use rustc_hir::def::CtorKind; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_span::symbol::Symbol; use rustc_span::Pos; use rustdoc_json_types::*; @@ -25,32 +26,37 @@ impl JsonRenderer<'_> { let item_type = ItemType::from(&item); let deprecation = item.deprecation(self.tcx); let clean::Item { source, name, attrs, kind, visibility, def_id } = item; - match *kind { - clean::StrippedItem(_) => None, - kind => Some(Item { - id: from_def_id(def_id), - crate_id: def_id.krate.as_u32(), - name: name.map(|sym| sym.to_string()), - source: self.convert_span(source), - visibility: self.convert_visibility(visibility), - docs: attrs.collapsed_doc_value(), - links: attrs - .links - .into_iter() - .filter_map(|clean::ItemLink { link, did, .. }| { - did.map(|did| (link, from_def_id(did))) - }) - .collect(), - attrs: attrs - .other_attrs - .iter() - .map(rustc_ast_pretty::pprust::attribute_to_string) - .collect(), - deprecation: deprecation.map(from_deprecation), - kind: item_type.into(), - inner: from_clean_item_kind(kind, self.tcx), - }), - } + let inner = match *kind { + clean::ItemKind::ExternCrateItem { ref src } => ItemEnum::ExternCrateItem { + name: name.as_ref().unwrap().to_string(), + rename: src.map(|x| x.to_string()), + }, + clean::StrippedItem(_) => return None, + x => from_clean_item_kind(x, self.tcx), + }; + Some(Item { + id: from_def_id(def_id), + crate_id: def_id.krate.as_u32(), + name: name.map(|sym| sym.to_string()), + source: self.convert_span(source), + visibility: self.convert_visibility(visibility), + docs: attrs.collapsed_doc_value(), + links: attrs + .links + .into_iter() + .filter_map(|clean::ItemLink { link, did, .. }| { + did.map(|did| (link, from_def_id(did))) + }) + .collect(), + attrs: attrs + .other_attrs + .iter() + .map(rustc_ast_pretty::pprust::attribute_to_string) + .collect(), + deprecation: deprecation.map(from_deprecation), + kind: item_type.into(), + inner, + }) } fn convert_span(&self, span: clean::Span) -> Option { @@ -153,9 +159,6 @@ fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum { use clean::ItemKind::*; match item { ModuleItem(m) => ItemEnum::ModuleItem(m.into()), - ExternCrateItem(c, a) => { - ItemEnum::ExternCrateItem { name: c.to_string(), rename: a.map(|x| x.to_string()) } - } ImportItem(i) => ItemEnum::ImportItem(i.into()), StructItem(s) => ItemEnum::StructItem(s.into()), UnionItem(u) => ItemEnum::UnionItem(u.into()), @@ -186,6 +189,7 @@ fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum { PrimitiveItem(_) | KeywordItem(_) => { panic!("{:?} is not supported for JSON output", item) } + ExternCrateItem { .. } => unreachable!(), } } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index e6edf33d23c8d..863610baed484 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -183,7 +183,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { match &*item.kind { // These don't have names so they don't get added to the output by default ImportItem(_) => self.item(item.clone()).unwrap(), - ExternCrateItem(_, _) => self.item(item.clone()).unwrap(), + ExternCrateItem { .. } => self.item(item.clone()).unwrap(), ImplItem(i) => i.items.iter().for_each(|i| self.item(i.clone()).unwrap()), _ => {} } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index bb54523871c3e..0e975128628ac 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -193,7 +193,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { // don't count items in stripped modules return Some(i); } - clean::ImportItem(..) | clean::ExternCrateItem(..) => { + clean::ImportItem(..) | clean::ExternCrateItem { .. } => { // docs on `use` and `extern crate` statements are not displayed, so they're not // worth counting return Some(i); diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index ede9e18a511a8..2fa9179515de1 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -63,7 +63,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo | clean::TypedefItem(_, _) | clean::StaticItem(_) | clean::ConstantItem(_) - | clean::ExternCrateItem(_, _) + | clean::ExternCrateItem { .. } | clean::ImportItem(_) | clean::PrimitiveItem(_) | clean::KeywordItem(_) diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 162b70973b418..44d54563f27a2 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -66,7 +66,7 @@ impl<'a> DocFolder for Stripper<'a> { } // handled in the `strip-priv-imports` pass - clean::ExternCrateItem(..) | clean::ImportItem(..) => {} + clean::ExternCrateItem { .. } | clean::ImportItem(..) => {} clean::ImplItem(..) => {} @@ -161,7 +161,9 @@ crate struct ImportStripper; impl DocFolder for ImportStripper { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { - clean::ExternCrateItem(..) | clean::ImportItem(..) if !i.visibility.is_public() => None, + clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => { + None + } _ => Some(self.fold_item_recur(i)), } } From 286a3570454b08fbf7fae890f19500190f55e0dc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Mar 2021 16:05:07 +0100 Subject: [PATCH 2/2] Refactor from_clean_item_kind to improve ExternCrateItem handling --- src/librustdoc/json/conversions.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index a579b66134531..47e4f3f0aa320 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -27,12 +27,8 @@ impl JsonRenderer<'_> { let deprecation = item.deprecation(self.tcx); let clean::Item { source, name, attrs, kind, visibility, def_id } = item; let inner = match *kind { - clean::ItemKind::ExternCrateItem { ref src } => ItemEnum::ExternCrateItem { - name: name.as_ref().unwrap().to_string(), - rename: src.map(|x| x.to_string()), - }, clean::StrippedItem(_) => return None, - x => from_clean_item_kind(x, self.tcx), + x => from_clean_item_kind(x, self.tcx, &name), }; Some(Item { id: from_def_id(def_id), @@ -155,7 +151,7 @@ crate fn from_def_id(did: DefId) -> Id { Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))) } -fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum { +fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>, name: &Option) -> ItemEnum { use clean::ItemKind::*; match item { ModuleItem(m) => ItemEnum::ModuleItem(m.into()), @@ -185,11 +181,14 @@ fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum { bounds: g.into_iter().map(Into::into).collect(), default: t.map(Into::into), }, - StrippedItem(inner) => from_clean_item_kind(*inner, tcx), + StrippedItem(inner) => from_clean_item_kind(*inner, tcx, name), PrimitiveItem(_) | KeywordItem(_) => { panic!("{:?} is not supported for JSON output", item) } - ExternCrateItem { .. } => unreachable!(), + ExternCrateItem { ref src } => ItemEnum::ExternCrateItem { + name: name.as_ref().unwrap().to_string(), + rename: src.map(|x| x.to_string()), + }, } }