From 0043fc9ce6e5482bda8e4a1b8c4c195332a877b9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 22 Nov 2020 13:34:06 -0500 Subject: [PATCH] Get rid of `doctree::Impl` --- src/librustdoc/clean/mod.rs | 102 +++++++++---------- src/librustdoc/core.rs | 16 --- src/librustdoc/doctree.rs | 18 ---- src/librustdoc/visit_ast.rs | 30 +----- src/test/rustdoc-ui/intra-link-errors.stderr | 18 ++-- 5 files changed, 60 insertions(+), 124 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d58a88957df22..e76ca1022a943 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -234,9 +234,8 @@ impl Clean for doctree::Module<'_> { 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.items.iter().map(|x| x.clean(cx))); + items.extend(self.items.iter().map(|x| x.clean(cx)).flatten()); 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))); @@ -1922,8 +1921,8 @@ impl Clean for hir::BareFnTy<'_> { } } -impl Clean for (&hir::Item<'_>, Option) { - fn clean(&self, cx: &DocContext<'_>) -> Item { +impl Clean> for (&hir::Item<'_>, Option) { + fn clean(&self, cx: &DocContext<'_>) -> Vec { use hir::ItemKind; let (item, renamed) = self; @@ -1977,10 +1976,11 @@ impl Clean for (&hir::Item<'_>, Option) { fields: variant_data.fields().clean(cx), fields_stripped: false, }), + ItemKind::Impl { .. } => return clean_impl(item, cx), _ => unreachable!("not yet converted"), }; - Item::from_def_id_and_parts(def_id, Some(name), kind, cx) + vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] } } @@ -2005,57 +2005,53 @@ 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(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec { + let mut ret = Vec::new(); + let (trait_, items, for_, unsafety, generics) = match &impl_.kind { + hir::ItemKind::Impl { of_trait, items, self_ty, unsafety, generics, .. } => { + (of_trait, items, self_ty, *unsafety, generics) } - - 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, + _ => unreachable!(), + }; + let trait_ = trait_.clean(cx); + let items = items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect::>(); + let def_id = cx.tcx.hir().local_def_id(impl_.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_ = 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| { + let 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, }); - 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 + Item::from_hir_id_and_parts(impl_.hir_id, None, kind, cx) + }; + 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 } impl Clean> for doctree::ExternCrate<'_> { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 413f5bdf5214b..b7cc0f1945911 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -1,4 +1,3 @@ -use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{self, Lrc}; use rustc_driver::abort_on_err; @@ -156,21 +155,6 @@ impl<'tcx> DocContext<'tcx> { def_id.as_local().map(|def_id| self.tcx.hir().local_def_id_to_hir_id(def_id)) } } - - crate fn stability(&self, id: HirId) -> Option { - self.tcx - .hir() - .opt_local_def_id(id) - .and_then(|def_id| self.tcx.lookup_stability(def_id.to_def_id())) - .cloned() - } - - crate fn deprecation(&self, id: HirId) -> Option { - self.tcx - .hir() - .opt_local_def_id(id) - .and_then(|def_id| self.tcx.lookup_deprecation(def_id.to_def_id())) - } } /// Creates a new diagnostic `Handler` that can be used to emit warnings and errors. diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index d56328cc2aa08..4d2fe04123bc2 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -23,7 +23,6 @@ crate struct Module<'hir> { // (item, renamed) crate items: Vec<(&'hir hir::Item<'hir>, Option)>, crate traits: Vec>, - crate impls: Vec>, crate foreigns: Vec>, crate macros: Vec, crate proc_macros: Vec, @@ -44,7 +43,6 @@ impl Module<'hir> { mods: Vec::new(), items: Vec::new(), traits: Vec::new(), - impls: Vec::new(), foreigns: Vec::new(), macros: Vec::new(), proc_macros: Vec::new(), @@ -89,22 +87,6 @@ crate struct Trait<'hir> { crate id: hir::HirId, } -#[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, -} - crate struct ForeignItem<'hir> { crate id: hir::HirId, crate name: Symbol, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index c55e5f7690c14..37050a57ca017 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -401,37 +401,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; om.traits.push(t); } - hir::ItemKind::Impl { - unsafety, - polarity, - defaultness, - constness, - defaultness_span: _, - ref generics, - ref of_trait, - self_ty, - ref items, - } => { + hir::ItemKind::Impl { ref of_trait, .. } => { // 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); + om.items.push((item, None)); } } } diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index 31e7fc48afde5..be98cac94ece7 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -106,6 +106,15 @@ LL | /// [S!] | this link resolves to the struct `S`, which is not in the macro namespace | help: to link to the struct, prefix with `struct@`: `struct@S` +error: unresolved link to `S::h` + --> $DIR/intra-link-errors.rs:78:6 + | +LL | /// [type@S::h] + | ^^^^^^^^^ + | | + | this link resolves to the associated function `h`, which is not in the type namespace + | help: to link to the associated function, add parentheses: `S::h()` + error: unresolved link to `T::g` --> $DIR/intra-link-errors.rs:86:6 | @@ -121,15 +130,6 @@ error: unresolved link to `T::h` LL | /// [T::h!] | ^^^^^ the trait `T` has no macro named `h` -error: unresolved link to `S::h` - --> $DIR/intra-link-errors.rs:78:6 - | -LL | /// [type@S::h] - | ^^^^^^^^^ - | | - | this link resolves to the associated function `h`, which is not in the type namespace - | help: to link to the associated function, add parentheses: `S::h()` - error: unresolved link to `m` --> $DIR/intra-link-errors.rs:98:6 |