impl Clean<Item> for doctree::Module<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let mut items: Vec<Item> = vec![];
- items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
items.extend(self.mods.iter().map(|x| x.clean(cx)));
items.extend(self.items.iter().map(|x| x.clean(cx)).flatten());
impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
- let bound_predicate = self.bound_atom();
+ let bound_predicate = self.kind();
match bound_predicate.skip_binder() {
- ty::PredicateAtom::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)),
- ty::PredicateAtom::RegionOutlives(pred) => pred.clean(cx),
- ty::PredicateAtom::TypeOutlives(pred) => pred.clean(cx),
- ty::PredicateAtom::Projection(pred) => Some(pred.clean(cx)),
-
- ty::PredicateAtom::Subtype(..)
- | ty::PredicateAtom::WellFormed(..)
- | ty::PredicateAtom::ObjectSafe(..)
- | ty::PredicateAtom::ClosureKind(..)
- | ty::PredicateAtom::ConstEvaluatable(..)
- | ty::PredicateAtom::ConstEquate(..)
- | ty::PredicateAtom::TypeWellFormedFromEnv(..) => panic!("not user writable"),
+ ty::PredicateKind::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)),
+ ty::PredicateKind::RegionOutlives(pred) => pred.clean(cx),
+ ty::PredicateKind::TypeOutlives(pred) => pred.clean(cx),
+ ty::PredicateKind::Projection(pred) => Some(pred.clean(cx)),
+
+ ty::PredicateKind::Subtype(..)
+ | ty::PredicateKind::WellFormed(..)
+ | ty::PredicateKind::ObjectSafe(..)
+ | ty::PredicateKind::ClosureKind(..)
+ | ty::PredicateKind::ConstEvaluatable(..)
+ | ty::PredicateKind::ConstEquate(..)
+ | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
}
}
}
.flat_map(|(p, _)| {
let mut projection = None;
let param_idx = (|| {
- let bound_p = p.bound_atom();
+ let bound_p = p.kind();
match bound_p.skip_binder() {
- ty::PredicateAtom::Trait(pred, _constness) => {
+ ty::PredicateKind::Trait(pred, _constness) => {
if let ty::Param(param) = pred.self_ty().kind() {
return Some(param.index);
}
}
- ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
+ ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
if let ty::Param(param) = ty.kind() {
return Some(param.index);
}
}
- ty::PredicateAtom::Projection(p) => {
+ ty::PredicateKind::Projection(p) => {
if let ty::Param(param) = p.projection_ty.self_ty().kind() {
projection = Some(bound_p.rebind(p));
return Some(param.index);
let mut ty_substs = FxHashMap::default();
let mut lt_substs = FxHashMap::default();
let mut ct_substs = FxHashMap::default();
- let generic_args = provided_params.generic_args();
+ let generic_args = provided_params.args();
{
let mut indices: GenericParamCount = Default::default();
for param in generics.params.iter() {
let mut bounds = bounds
.iter()
.filter_map(|bound| {
- // Note: The substs of opaque types can contain unbound variables,
- // meaning that we have to use `ignore_quantifiers_with_unbound_vars` here.
- let bound_predicate = bound.bound_atom_with_opt_escaping(cx.tcx);
+ let bound_predicate = bound.kind();
let trait_ref = match bound_predicate.skip_binder() {
- ty::PredicateAtom::Trait(tr, _constness) => {
+ ty::PredicateKind::Trait(tr, _constness) => {
bound_predicate.rebind(tr.trait_ref)
}
- ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
+ ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
if let Some(r) = reg.clean(cx) {
regions.push(GenericBound::Outlives(r));
}
let bounds: Vec<_> = bounds
.iter()
.filter_map(|bound| {
- if let ty::PredicateAtom::Projection(proj) =
- bound.bound_atom_with_opt_escaping(cx.tcx).skip_binder()
+ if let ty::PredicateKind::Projection(proj) =
+ bound.kind().skip_binder()
{
if proj.projection_ty.trait_ref(cx.tcx)
== trait_ref.skip_binder()
}
}
-impl Clean<Item> 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 }
- }
-}
-
impl Clean<Item> for ty::VariantDef {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let kind = match self.ctor_kind {
- CtorKind::Const => VariantKind::CLike,
- CtorKind::Fn => VariantKind::Tuple(
+ CtorKind::Const => Variant::CLike,
+ CtorKind::Fn => Variant::Tuple(
self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect(),
),
- CtorKind::Fictive => VariantKind::Struct(VariantStruct {
+ CtorKind::Fictive => Variant::Struct(VariantStruct {
struct_type: doctree::Plain,
fields_stripped: false,
fields: self
.collect(),
}),
};
- let what_rustc_thinks = Item::from_def_id_and_parts(
- self.def_id,
- Some(self.ident.name),
- VariantItem(Variant { kind }),
- cx,
- );
+ let what_rustc_thinks =
+ Item::from_def_id_and_parts(self.def_id, Some(self.ident.name), VariantItem(kind), cx);
// don't show `pub` for fields, which are always public
Item { visibility: Inherited, ..what_rustc_thinks }
}
}
-impl Clean<VariantKind> for hir::VariantData<'_> {
- fn clean(&self, cx: &DocContext<'_>) -> VariantKind {
+impl Clean<Variant> for hir::VariantData<'_> {
+ fn clean(&self, cx: &DocContext<'_>) -> Variant {
match self {
- hir::VariantData::Struct(..) => VariantKind::Struct(self.clean(cx)),
+ hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)),
hir::VariantData::Tuple(..) => {
- VariantKind::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
+ Variant::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
}
- hir::VariantData::Unit(..) => VariantKind::CLike,
+ hir::VariantData::Unit(..) => Variant::CLike,
}
}
}
impl Clean<PathSegment> for hir::PathSegment<'_> {
fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
- PathSegment { name: self.ident.name, args: self.generic_args().clean(cx) }
+ PathSegment { name: self.ident.name, args: self.args().clean(cx) }
}
}
fields: variant_data.fields().clean(cx),
fields_stripped: false,
}),
- ItemKind::Impl { .. } => return clean_impl(item, cx),
+ ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.hir_id, cx),
// proc macros can have a name set by attributes
ItemKind::Fn(ref sig, ref generics, body_id) => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
- hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
+ ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
let items = item_ids
.iter()
.map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx))
ItemKind::ExternCrate(orig_name) => {
return clean_extern_crate(item, name, orig_name, cx);
}
+ ItemKind::Use(path, kind) => {
+ return clean_use_statement(item, name, path, kind, cx);
+ }
_ => unreachable!("not yet converted"),
};
impl Clean<Item> for hir::Variant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
- let kind = VariantItem(Variant { kind: self.data.clean(cx) });
+ let kind = VariantItem(self.data.clean(cx));
let what_rustc_thinks =
Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
// don't show `pub` for variants, which are always public
}
}
-fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec<Item> {
+fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, 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)
- }
- _ => 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);
+ let trait_ = impl_.of_trait.clean(cx);
+ let items =
+ impl_.items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
+ let def_id = cx.tcx.hir().local_def_id(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.
.map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
.unwrap_or_default();
- let for_ = for_.clean(cx);
+ let for_ = impl_.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<Type>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Impl {
- unsafety,
- generics: generics.clean(cx),
+ unsafety: impl_.unsafety,
+ generics: impl_.generics.clean(cx),
provided_trait_methods: provided.clone(),
trait_,
for_,
synthetic: false,
blanket_impl: None,
});
- Item::from_hir_id_and_parts(impl_.hir_id, None, kind, cx)
+ Item::from_hir_id_and_parts(hir_id, None, kind, cx)
};
if let Some(type_alias) = type_alias {
ret.push(make_item(trait_.clone(), type_alias, items.clone()));
// FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
vec![Item {
name: None,
- attrs: krate.attrs.clean(cx),
+ attrs: box krate.attrs.clean(cx),
source: krate.span.clean(cx),
def_id: crate_def_id,
visibility: krate.vis.clean(cx),
}]
}
-impl Clean<Vec<Item>> for doctree::Import<'_> {
- fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
- // We need this comparison because some imports (for std types for example)
- // are "inserted" as well but directly by the compiler and they should not be
- // taken into account.
- if self.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::StdImports) {
- return Vec::new();
- }
-
- let (doc_meta_item, please_inline) = self.attrs.lists(sym::doc).get_word_attr(sym::inline);
- let pub_underscore = self.vis.node.is_pub() && self.name == kw::Underscore;
-
- if pub_underscore && please_inline {
- rustc_errors::struct_span_err!(
- cx.tcx.sess,
- doc_meta_item.unwrap().span(),
- E0780,
- "anonymous imports cannot be inlined"
- )
- .span_label(self.span, "anonymous import")
- .emit();
- }
+fn clean_use_statement(
+ import: &hir::Item<'_>,
+ name: Symbol,
+ path: &hir::Path<'_>,
+ kind: hir::UseKind,
+ cx: &DocContext<'_>,
+) -> Vec<Item> {
+ // We need this comparison because some imports (for std types for example)
+ // are "inserted" as well but directly by the compiler and they should not be
+ // taken into account.
+ if import.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::StdImports) {
+ return Vec::new();
+ }
+
+ let (doc_meta_item, please_inline) = import.attrs.lists(sym::doc).get_word_attr(sym::inline);
+ let pub_underscore = import.vis.node.is_pub() && name == kw::Underscore;
+
+ if pub_underscore && please_inline {
+ rustc_errors::struct_span_err!(
+ cx.tcx.sess,
+ doc_meta_item.unwrap().span(),
+ E0780,
+ "anonymous imports cannot be inlined"
+ )
+ .span_label(import.span, "anonymous import")
+ .emit();
+ }
- // We consider inlining the documentation of `pub use` statements, but we
- // forcefully don't inline if this is not public or if the
- // #[doc(no_inline)] attribute is present.
- // Don't inline doc(hidden) imports so they can be stripped at a later stage.
- let mut denied = !self.vis.node.is_pub()
- || pub_underscore
- || self.attrs.iter().any(|a| {
- a.has_name(sym::doc)
- && match a.meta_item_list() {
- Some(l) => {
- attr::list_contains_name(&l, sym::no_inline)
- || attr::list_contains_name(&l, sym::hidden)
- }
- None => false,
+ // We consider inlining the documentation of `pub use` statements, but we
+ // forcefully don't inline if this is not public or if the
+ // #[doc(no_inline)] attribute is present.
+ // Don't inline doc(hidden) imports so they can be stripped at a later stage.
+ let mut denied = !import.vis.node.is_pub()
+ || pub_underscore
+ || import.attrs.iter().any(|a| {
+ a.has_name(sym::doc)
+ && match a.meta_item_list() {
+ Some(l) => {
+ attr::list_contains_name(&l, sym::no_inline)
+ || attr::list_contains_name(&l, sym::hidden)
}
- });
- // Also check whether imports were asked to be inlined, in case we're trying to re-export a
- // crate in Rust 2018+
- let path = self.path.clean(cx);
- let inner = if self.glob {
- if !denied {
- let mut visited = FxHashSet::default();
- if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
- return items;
+ None => false,
}
+ });
+
+ // Also check whether imports were asked to be inlined, in case we're trying to re-export a
+ // crate in Rust 2018+
+ let def_id = cx.tcx.hir().local_def_id(import.hir_id).to_def_id();
+ let path = path.clean(cx);
+ let inner = if kind == hir::UseKind::Glob {
+ if !denied {
+ let mut visited = FxHashSet::default();
+ if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
+ return items;
}
- Import::new_glob(resolve_use_source(cx, path), true)
- } else {
- let name = self.name;
- if !please_inline {
- if let Res::Def(DefKind::Mod, did) = path.res {
- if !did.is_local() && did.index == CRATE_DEF_INDEX {
- // if we're `pub use`ing an extern crate root, don't inline it unless we
- // were specifically asked for it
- denied = true;
- }
+ }
+ Import::new_glob(resolve_use_source(cx, path), true)
+ } else {
+ if !please_inline {
+ if let Res::Def(DefKind::Mod, did) = path.res {
+ if !did.is_local() && did.index == CRATE_DEF_INDEX {
+ // if we're `pub use`ing an extern crate root, don't inline it unless we
+ // were specifically asked for it
+ denied = true;
}
}
- if !denied {
- let mut visited = FxHashSet::default();
+ }
+ if !denied {
+ let mut visited = FxHashSet::default();
- if let Some(mut items) = inline::try_inline(
+ if let Some(mut items) = inline::try_inline(
+ cx,
+ cx.tcx.parent_module(import.hir_id).to_def_id(),
+ path.res,
+ name,
+ Some(import.attrs),
+ &mut visited,
+ ) {
+ items.push(Item::from_def_id_and_parts(
+ def_id,
+ None,
+ ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
cx,
- cx.tcx.parent_module(self.id).to_def_id(),
- path.res,
- name,
- Some(self.attrs),
- &mut visited,
- ) {
- items.push(Item {
- name: None,
- attrs: self.attrs.clean(cx),
- source: self.span.clean(cx),
- def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
- visibility: self.vis.clean(cx),
- kind: box ImportItem(Import::new_simple(
- self.name,
- resolve_use_source(cx, path),
- false,
- )),
- });
- return items;
- }
+ ));
+ return items;
}
- Import::new_simple(name, resolve_use_source(cx, path), true)
- };
+ }
+ Import::new_simple(name, resolve_use_source(cx, path), true)
+ };
- vec![Item {
- name: None,
- attrs: self.attrs.clean(cx),
- source: self.span.clean(cx),
- def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
- visibility: self.vis.clean(cx),
- kind: box ImportItem(inner),
- }]
- }
+ vec![Item::from_def_id_and_parts(def_id, None, ImportItem(inner), cx)]
}
impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {