Skip to content

Get rid of doctree::ForeignItem #79314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 57 additions & 62 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,8 @@ impl Clean<Item> 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)));

Expand Down Expand Up @@ -1922,8 +1921,8 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
}
}

impl Clean<Item> for (&hir::Item<'_>, Option<Ident>) {
fn clean(&self, cx: &DocContext<'_>) -> Item {
impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Ident>) {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
use hir::ItemKind;

let (item, renamed) = self;
Expand Down Expand Up @@ -1977,10 +1976,11 @@ impl Clean<Item> for (&hir::Item<'_>, Option<Ident>) {
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)]
}
}

Expand All @@ -2005,57 +2005,53 @@ impl Clean<ImplPolarity> for ty::ImplPolarity {
}
}

impl Clean<Vec<Item>> for doctree::Impl<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
let mut ret = Vec::new();
let trait_ = self.trait_.clean(cx);
let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>();
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<Item> {
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<String> = 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::<Vec<_>>();
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<String> = 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<Type>, for_: Type, items: Vec<Item>| {
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<Type>, for_: Type, items: Vec<Item>| 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<Vec<Item>> for doctree::ExternCrate<'_> {
Expand Down Expand Up @@ -2190,11 +2186,12 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
}
}

impl Clean<Item> for doctree::ForeignItem<'_> {
impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Ident>) {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let kind = match self.kind {
let (item, renamed) = self;
let kind = match item.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(item.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);
Expand All @@ -2211,15 +2208,13 @@ impl Clean<Item> 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(item.hir_id, Some(renamed.unwrap_or(item.ident).name), kind, cx)
}
}

Expand Down
16 changes: 0 additions & 16 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<attr::Stability> {
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<attr::Deprecation> {
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.
Expand Down
26 changes: 1 addition & 25 deletions src/librustdoc/doctree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ crate struct Module<'hir> {
// (item, renamed)
crate items: Vec<(&'hir hir::Item<'hir>, Option<Ident>)>,
crate traits: Vec<Trait<'hir>>,
crate impls: Vec<Impl<'hir>>,
crate foreigns: Vec<ForeignItem<'hir>>,
crate foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Ident>)>,
crate macros: Vec<Macro>,
crate proc_macros: Vec<ProcMacro>,
crate is_crate: bool,
Expand All @@ -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(),
Expand Down Expand Up @@ -89,28 +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<hir::TraitRef<'hir>>,
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,
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 {
Expand Down
40 changes: 4 additions & 36 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
}
Expand All @@ -444,15 +418,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
om: &mut Module<'tcx>,
) {
// If inlining we only want to include public functions.
if self.inlining && !item.vis.node.is_pub() {
return;
if !self.inlining || item.vis.node.is_pub() {
om.foreigns.push((item, renamed));
}

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.
Expand Down
18 changes: 9 additions & 9 deletions src/test/rustdoc-ui/intra-link-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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
|
Expand Down