Skip to content
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

rustdoc: Cleanup clean part 1 #88810

Merged
merged 8 commits into from
Sep 12, 2021
Merged
36 changes: 10 additions & 26 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,7 @@ impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
);
}
inline::record_extern_fqn(cx, trait_ref.def_id, kind);
let path = external_path(
cx,
cx.tcx.item_name(trait_ref.def_id),
Some(trait_ref.def_id),
true,
bounds.to_vec(),
trait_ref.substs,
);
let path = external_path(cx, trait_ref.def_id, true, bounds.to_vec(), trait_ref.substs);

debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs);

Expand Down Expand Up @@ -906,7 +899,7 @@ impl Clean<bool> for hir::IsAuto {
impl Clean<Type> for hir::TraitRef<'_> {
fn clean(&self, cx: &mut DocContext<'_>) -> Type {
let path = self.path.clean(cx);
resolve_type(cx, path, self.hir_ref_id)
resolve_type(cx, path)
}
}

Expand Down Expand Up @@ -1164,7 +1157,7 @@ impl Clean<Item> for ty::AssocItem {

fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
use rustc_hir::GenericParamCount;
let hir::Ty { hir_id, span, ref kind } = *hir_ty;
let hir::Ty { hir_id: _, span, ref kind } = *hir_ty;
let qpath = match kind {
hir::TyKind::Path(qpath) => qpath,
_ => unreachable!(),
Expand Down Expand Up @@ -1271,7 +1264,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
return cx.enter_alias(ty_substs, lt_substs, ct_substs, |cx| ty.clean(cx));
}
let path = path.clean(cx);
resolve_type(cx, path, hir_id)
resolve_type(cx, path)
}
hir::QPath::Resolved(Some(ref qself), ref p) => {
// Try to normalize `<X as Y>::T` to a type
Expand All @@ -1292,7 +1285,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
name: p.segments.last().expect("segments were empty").ident.name,
self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)),
self_type: Box::new(qself.clean(cx)),
trait_: Box::new(resolve_type(cx, trait_path, hir_id)),
trait_: Box::new(resolve_type(cx, trait_path)),
}
}
hir::QPath::TypeRelative(ref qself, ref segment) => {
Expand All @@ -1308,7 +1301,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
name: segment.ident.name,
self_def_id: res.opt_def_id(),
self_type: Box::new(qself.clean(cx)),
trait_: Box::new(resolve_type(cx, trait_path, hir_id)),
trait_: Box::new(resolve_type(cx, trait_path)),
}
}
hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
Expand Down Expand Up @@ -1448,19 +1441,12 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
AdtKind::Enum => ItemType::Enum,
};
inline::record_extern_fqn(cx, did, kind);
let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
let path = external_path(cx, did, false, vec![], substs);
ResolvedPath { path, did, is_generic: false }
}
ty::Foreign(did) => {
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
let path = external_path(
cx,
cx.tcx.item_name(did),
None,
false,
vec![],
InternalSubsts::empty(),
);
let path = external_path(cx, did, false, vec![], InternalSubsts::empty());
ResolvedPath { path, did, is_generic: false }
}
ty::Dynamic(ref obj, ref reg) => {
Expand All @@ -1484,8 +1470,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {

for did in dids {
let empty = cx.tcx.intern_substs(&[]);
let path =
external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
let path = external_path(cx, did, false, vec![], empty);
inline::record_extern_fqn(cx, did, ItemType::Trait);
let bound = PolyTrait {
trait_: ResolvedPath { path, did, is_generic: false },
Expand All @@ -1502,8 +1487,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
});
}

let path =
external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs);
let path = external_path(cx, did, false, bindings, substs);
bounds.insert(
0,
PolyTrait {
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,7 @@ impl GenericBound {
crate fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
let did = cx.tcx.require_lang_item(LangItem::Sized, None);
let empty = cx.tcx.intern_substs(&[]);
let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
let path = external_path(cx, did, false, vec![], empty);
inline::record_extern_fqn(cx, did, ItemType::Trait);
GenericBound::TraitBound(
PolyTrait {
Expand Down
54 changes: 23 additions & 31 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
let krate = cx.tcx.hir().krate();
let module = crate::visit_ast::RustdocVisitor::new(cx).visit(krate);

cx.cache.deref_trait_did = cx.tcx.lang_items().deref_trait();
cx.cache.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
cx.cache.owned_box_did = cx.tcx.lang_items().owned_box();

let mut externs = Vec::new();
for &cnum in cx.tcx.crates(()).iter() {
externs.push(ExternalCrate { crate_num: cnum });
Expand Down Expand Up @@ -97,7 +93,7 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {

fn external_generic_args(
cx: &mut DocContext<'_>,
trait_did: Option<DefId>,
did: DefId,
has_self: bool,
bindings: Vec<TypeBinding>,
substs: SubstsRef<'_>,
Expand Down Expand Up @@ -125,42 +121,38 @@ fn external_generic_args(
})
.collect();

match trait_did {
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
Some(did) if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() => {
assert!(ty_kind.is_some());
let inputs = match ty_kind {
Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
_ => return GenericArgs::AngleBracketed { args, bindings },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
// match types[1].kind {
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
// _ => Some(types[1].clean(cx))
// };
GenericArgs::Parenthesized { inputs, output }
}
_ => GenericArgs::AngleBracketed { args, bindings },
if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
let inputs = match ty_kind.unwrap() {
ty::Tuple(tys) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
_ => return GenericArgs::AngleBracketed { args, bindings },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
// match types[1].kind {
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
// _ => Some(types[1].clean(cx))
// };
GenericArgs::Parenthesized { inputs, output }
} else {
GenericArgs::AngleBracketed { args, bindings }
}
}

// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
// from Fn<(A, B,), C> to Fn(A, B) -> C
pub(super) fn external_path(
cx: &mut DocContext<'_>,
name: Symbol,
trait_did: Option<DefId>,
did: DefId,
has_self: bool,
bindings: Vec<TypeBinding>,
substs: SubstsRef<'_>,
) -> Path {
let def_kind = cx.tcx.def_kind(did);
let name = cx.tcx.item_name(did);
Path {
global: false,
res: Res::Err,
res: Res::Def(def_kind, did),
segments: vec![PathSegment {
name,
args: external_generic_args(cx, trait_did, has_self, bindings, substs),
args: external_generic_args(cx, did, has_self, bindings, substs),
}],
}
}
Expand Down Expand Up @@ -409,16 +401,16 @@ crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
}

/// Given a type Path, resolve it to a Type using the TyCtxt
crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Type {
debug!("resolve_type({:?},{:?})", path, id);
crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
debug!("resolve_type({:?})", path);

let is_generic = match path.res {
Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)),
Res::SelfTy(..) if path.segments.len() == 1 => {
return Generic(kw::SelfUpper);
}
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
return Generic(Symbol::intern(&path.whole_name()));
return Generic(path.segments[0].name);
}
Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
_ => false,
Expand Down
3 changes: 0 additions & 3 deletions src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ crate struct Cache {
stripped_mod: bool,

crate search_index: Vec<IndexItem>,
crate deref_trait_did: Option<DefId>,
crate deref_mut_trait_did: Option<DefId>,
crate owned_box_did: Option<DefId>,

// In rare case where a structure is defined in one module but implemented
// in another, if the implementing module is parsed before defining module,
Expand Down
46 changes: 24 additions & 22 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId;
use rustc_hir::Mutability;
use rustc_middle::middle::stability;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::{kw, sym, Symbol};
use serde::ser::SerializeSeq;
use serde::{Serialize, Serializer};
Expand Down Expand Up @@ -1069,13 +1070,13 @@ fn render_assoc_items(
return;
}
if !traits.is_empty() {
let deref_impl = traits
.iter()
.find(|t| t.inner_impl().trait_.def_id_full(cache) == cache.deref_trait_did);
let deref_impl = traits.iter().find(|t| {
t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
});
if let Some(impl_) = deref_impl {
let has_deref_mut = traits
.iter()
.any(|t| t.inner_impl().trait_.def_id_full(cache) == cache.deref_mut_trait_did);
let has_deref_mut = traits.iter().any(|t| {
t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_mut_trait()
});
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
}
let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
Expand Down Expand Up @@ -1165,7 +1166,7 @@ fn render_deref_methods(
}
}

fn should_render_item(item: &clean::Item, deref_mut_: bool, cache: &Cache) -> bool {
fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
let self_type_opt = match *item.kind {
clean::MethodItem(ref method, _) => method.decl.self_type(),
clean::TyMethodItem(ref method) => method.decl.self_type(),
Expand All @@ -1179,7 +1180,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, cache: &Cache) -> bo
(mutability == Mutability::Mut, false, false)
}
SelfTy::SelfExplicit(clean::ResolvedPath { did, .. }) => {
(false, Some(did) == cache.owned_box_did, false)
(false, Some(did) == tcx.lang_items().owned_box(), false)
}
SelfTy::SelfValue => (false, false, true),
_ => (false, false, false),
Expand Down Expand Up @@ -1302,7 +1303,7 @@ fn render_impl(
&& match render_mode {
RenderMode::Normal => true,
RenderMode::ForDeref { mut_: deref_mut_ } => {
should_render_item(&item, deref_mut_, cx.cache())
should_render_item(&item, deref_mut_, cx.tcx())
}
};

Expand Down Expand Up @@ -1800,13 +1801,13 @@ fn get_methods(
for_deref: bool,
used_links: &mut FxHashSet<String>,
deref_mut: bool,
cache: &Cache,
tcx: TyCtxt<'_>,
) -> Vec<String> {
i.items
.iter()
.filter_map(|item| match item.name {
Some(ref name) if !name.is_empty() && item.is_method() => {
if !for_deref || should_render_item(item, deref_mut, cache) {
if !for_deref || should_render_item(item, deref_mut, tcx) {
Some(format!(
"<a href=\"#{}\">{}</a>",
get_next_url(used_links, format!("method.{}", name)),
Expand Down Expand Up @@ -1868,7 +1869,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
let mut ret = v
.iter()
.filter(|i| i.inner_impl().trait_.is_none())
.flat_map(move |i| get_methods(i.inner_impl(), false, used_links_bor, false, cache))
.flat_map(move |i| {
get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx())
})
.collect::<Vec<_>>();
if !ret.is_empty() {
// We want links' order to be reproducible so we don't use unstable sort.
Expand All @@ -1886,11 +1889,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
}

if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
if let Some(impl_) = v
.iter()
.filter(|i| i.inner_impl().trait_.is_some())
.find(|i| i.inner_impl().trait_.def_id_full(cache) == cache.deref_trait_did)
{
if let Some(impl_) = v.iter().filter(|i| i.inner_impl().trait_.is_some()).find(|i| {
i.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
}) {
sidebar_deref_methods(cx, out, impl_, v);
}

Expand Down Expand Up @@ -1988,10 +1989,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
}
}
}
let deref_mut = v
.iter()
.filter(|i| i.inner_impl().trait_.is_some())
.any(|i| i.inner_impl().trait_.def_id_full(c) == c.deref_mut_trait_did);
let deref_mut = v.iter().filter(|i| i.inner_impl().trait_.is_some()).any(|i| {
i.inner_impl().trait_.def_id_full(c) == cx.tcx().lang_items().deref_mut_trait()
});
let inner_impl = target
.def_id_full(c)
.or_else(|| {
Expand All @@ -2004,7 +2004,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
let mut ret = impls
.iter()
.filter(|i| i.inner_impl().trait_.is_none())
.flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c))
.flat_map(|i| {
get_methods(i.inner_impl(), true, &mut used_links, deref_mut, cx.tcx())
})
.collect::<Vec<_>>();
if !ret.is_empty() {
write!(
Expand Down
2 changes: 1 addition & 1 deletion src/test/rustdoc/synthetic_auto/no-redundancy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ where

// @has no_redundancy/struct.Outer.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<T> Send for Outer<T> where T: Copy + Send"
// "impl<T> Send for Outer<T> where T: Send + Copy"
pub struct Outer<T> {
inner_field: Inner<T>,
}