summaryrefslogtreecommitdiff
path: root/src/librustdoc/clean
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/clean')
-rw-r--r--src/librustdoc/clean/auto_trait.rs5
-rw-r--r--src/librustdoc/clean/inline.rs7
-rw-r--r--src/librustdoc/clean/mod.rs140
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/librustdoc/clean/utils.rs3
5 files changed, 109 insertions, 50 deletions
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index fb32b6ef1d3..baf2b0a8585 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -556,7 +556,10 @@ where
WherePredicate::EqPredicate { lhs, rhs, bound_params } => {
match *lhs {
Type::QPath(box QPathData {
- ref assoc, ref self_type, ref trait_, ..
+ ref assoc,
+ ref self_type,
+ trait_: Some(ref trait_),
+ ..
}) => {
let ty = &*self_type;
let mut new_trait = trait_.clone();
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 951f54e9366..c852f9cca2b 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -706,7 +706,12 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
g.where_predicates.retain(|pred| match pred {
clean::WherePredicate::BoundPredicate {
- ty: clean::QPath(box clean::QPathData { self_type: clean::Generic(ref s), trait_, .. }),
+ ty:
+ clean::QPath(box clean::QPathData {
+ self_type: clean::Generic(ref s),
+ trait_: Some(trait_),
+ ..
+ }),
bounds,
..
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 23449a25c3a..59a3e631724 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -119,7 +119,39 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
});
let kind = ModuleItem(Module { items, span });
- Item::from_def_id_and_parts(doc.def_id.to_def_id(), Some(doc.name), kind, cx)
+ generate_item_with_correct_attrs(cx, kind, doc.def_id, doc.name, doc.import_id, doc.renamed)
+}
+
+fn generate_item_with_correct_attrs(
+ cx: &mut DocContext<'_>,
+ kind: ItemKind,
+ local_def_id: LocalDefId,
+ name: Symbol,
+ import_id: Option<LocalDefId>,
+ renamed: Option<Symbol>,
+) -> Item {
+ let def_id = local_def_id.to_def_id();
+ let target_attrs = inline::load_attrs(cx, def_id);
+ let attrs = if let Some(import_id) = import_id {
+ let is_inline = inline::load_attrs(cx, import_id.to_def_id())
+ .lists(sym::doc)
+ .get_word_attr(sym::inline)
+ .is_some();
+ let mut attrs = get_all_import_attributes(cx, import_id, local_def_id, is_inline);
+ add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
+ attrs
+ } else {
+ // We only keep the item's attributes.
+ target_attrs.iter().map(|attr| (Cow::Borrowed(attr), None)).collect()
+ };
+
+ let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
+ let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
+
+ let name = renamed.or(Some(name));
+ let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, Box::new(attrs), cfg);
+ item.inline_stmt_id = import_id.map(|local| local.to_def_id());
+ item
}
fn clean_generic_bound<'tcx>(
@@ -441,7 +473,7 @@ fn clean_projection<'tcx>(
assoc: projection_to_path_segment(ty, cx),
should_show_cast,
self_type,
- trait_,
+ trait_: Some(trait_),
}))
}
@@ -1330,7 +1362,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
let mut bounds: Vec<GenericBound> = Vec::new();
generics.where_predicates.retain_mut(|pred| match *pred {
WherePredicate::BoundPredicate {
- ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }),
+ ty:
+ QPath(box QPathData {
+ ref assoc,
+ ref self_type,
+ trait_: Some(ref trait_),
+ ..
+ }),
bounds: ref mut pred_bounds,
..
} => {
@@ -1492,25 +1530,30 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx),
should_show_cast,
self_type,
- trait_,
+ trait_: Some(trait_),
}))
}
hir::QPath::TypeRelative(qself, segment) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
- let res = match ty.kind() {
+ let self_type = clean_ty(qself, cx);
+
+ let (trait_, should_show_cast) = match ty.kind() {
ty::Alias(ty::Projection, proj) => {
- Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id)
+ let res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
+ let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
+ register_res(cx, trait_.res);
+ let self_def_id = res.opt_def_id();
+ let should_show_cast =
+ compute_should_show_cast(self_def_id, &trait_, &self_type);
+
+ (Some(trait_), should_show_cast)
}
+ ty::Alias(ty::Inherent, _) => (None, false),
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
ty::Error(_) => return Type::Infer,
- // Otherwise, this is an inherent associated type.
- _ => return clean_middle_ty(ty::Binder::dummy(ty), cx, None),
+ _ => bug!("clean: expected associated type, found `{ty:?}`"),
};
- let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
- register_res(cx, trait_.res);
- let self_def_id = res.opt_def_id();
- let self_type = clean_ty(qself, cx);
- let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
+
Type::QPath(Box::new(QPathData {
assoc: clean_path_segment(segment, cx),
should_show_cast,
@@ -1836,6 +1879,29 @@ pub(crate) fn clean_middle_ty<'tcx>(
clean_projection(bound_ty.rebind(*data), cx, parent_def_id)
}
+ ty::Alias(ty::Inherent, alias_ty) => {
+ let alias_ty = bound_ty.rebind(alias_ty);
+ let self_type = clean_middle_ty(alias_ty.map_bound(|ty| ty.self_ty()), cx, None);
+
+ Type::QPath(Box::new(QPathData {
+ assoc: PathSegment {
+ name: cx.tcx.associated_item(alias_ty.skip_binder().def_id).name,
+ args: GenericArgs::AngleBracketed {
+ args: substs_to_args(
+ cx,
+ alias_ty.map_bound(|ty| ty.substs.as_slice()),
+ true,
+ )
+ .into(),
+ bindings: Default::default(),
+ },
+ },
+ should_show_cast: false,
+ self_type,
+ trait_: None,
+ }))
+ }
+
ty::Param(ref p) => {
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
ImplTrait(bounds)
@@ -2311,29 +2377,14 @@ fn clean_maybe_renamed_item<'tcx>(
_ => unreachable!("not yet converted"),
};
- let target_attrs = inline::load_attrs(cx, def_id);
- let attrs = if let Some(import_id) = import_id {
- let is_inline = inline::load_attrs(cx, import_id.to_def_id())
- .lists(sym::doc)
- .get_word_attr(sym::inline)
- .is_some();
- let mut attrs =
- get_all_import_attributes(cx, import_id, item.owner_id.def_id, is_inline);
- add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
- attrs
- } else {
- // We only keep the item's attributes.
- target_attrs.iter().map(|attr| (Cow::Borrowed(attr), None)).collect()
- };
-
- let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
- let attrs =
- Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
-
- let mut item =
- Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
- item.inline_stmt_id = import_id.map(|local| local.to_def_id());
- vec![item]
+ vec![generate_item_with_correct_attrs(
+ cx,
+ kind,
+ item.owner_id.def_id,
+ name,
+ import_id,
+ renamed,
+ )]
})
}
@@ -2363,14 +2414,15 @@ fn clean_impl<'tcx>(
}
let for_ = clean_ty(impl_.self_ty, cx);
- let type_alias = for_.def_id(&cx.cache).and_then(|did| match tcx.def_kind(did) {
- DefKind::TyAlias => Some(clean_middle_ty(
- ty::Binder::dummy(tcx.type_of(did).subst_identity()),
- cx,
- Some(did),
- )),
- _ => None,
- });
+ let type_alias =
+ for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) {
+ DefKind::TyAlias => Some(clean_middle_ty(
+ ty::Binder::dummy(tcx.type_of(def_id).subst_identity()),
+ cx,
+ Some(def_id.to_def_id()),
+ )),
+ _ => None,
+ });
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Box::new(Impl {
unsafety: impl_.unsafety,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7371b44465b..38664c3e359 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1660,7 +1660,7 @@ impl Type {
pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self {
- Some((self_type, trait_.def_id(), assoc.clone()))
+ Some((self_type, trait_.as_ref()?.def_id(), assoc.clone()))
} else {
None
}
@@ -1704,7 +1704,7 @@ pub(crate) struct QPathData {
pub self_type: Type,
/// FIXME: compute this field on demand.
pub should_show_cast: bool,
- pub trait_: Path,
+ pub trait_: Option<Path>,
}
/// A primitive (aka, builtin) type.
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index b802fd065fe..17aa6b38e38 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -594,9 +594,8 @@ pub(super) fn display_macro_source(
def_id: DefId,
vis: ty::Visibility<DefId>,
) -> String {
- let tts: Vec<_> = def.body.tokens.clone().into_trees().collect();
// Extract the spans of all matchers. They represent the "interface" of the macro.
- let matchers = tts.chunks(4).map(|arm| &arm[0]);
+ let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]);
if def.macro_rules {
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(cx.tcx, matchers, ";"))