From 44e6f2e90fa050c490c2d79a3c65866cb5be3b34 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 21 Aug 2021 20:58:23 -0700 Subject: [PATCH 1/8] Remove unnecessary `Cache.*_did` fields They can be obtained by accessing the `TyCtxt` where they are needed. --- src/librustdoc/clean/utils.rs | 4 --- src/librustdoc/formats/cache.rs | 3 --- src/librustdoc/html/render/mod.rs | 41 ++++++++++++++----------------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index de2cd60d2edcd..873ecd759ebbd 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -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 }); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 1830909d94460..a88f82dadda12 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -98,9 +98,6 @@ crate struct Cache { stripped_mod: bool, crate search_index: Vec, - crate deref_trait_did: Option, - crate deref_mut_trait_did: Option, - crate owned_box_did: Option, // In rare case where a structure is defined in one module but implemented // in another, if the implementing module is parsed before defining module, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 172fe5d164b7a..f8f71c6f3daf3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1069,13 +1069,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>) = @@ -1165,7 +1165,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, cx: &Context<'_>) -> bool { let self_type_opt = match *item.kind { clean::MethodItem(ref method, _) => method.decl.self_type(), clean::TyMethodItem(ref method) => method.decl.self_type(), @@ -1179,7 +1179,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) == cx.tcx().lang_items().owned_box(), false) } SelfTy::SelfValue => (false, false, true), _ => (false, false, false), @@ -1302,7 +1302,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) } }; @@ -1800,13 +1800,13 @@ fn get_methods( for_deref: bool, used_links: &mut FxHashSet, deref_mut: bool, - cache: &Cache, + cx: &Context<'_>, ) -> Vec { 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, cx) { Some(format!( "{}", get_next_url(used_links, format!("method.{}", name)), @@ -1868,7 +1868,7 @@ 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)) .collect::>(); if !ret.is_empty() { // We want links' order to be reproducible so we don't use unstable sort. @@ -1886,11 +1886,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); } @@ -1988,10 +1986,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(|| { @@ -2004,7 +2001,7 @@ 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)) .collect::>(); if !ret.is_empty() { write!( From df281ee57b3eb04184802da552b06d1b83a04ad3 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 27 Aug 2021 16:49:14 -0700 Subject: [PATCH 2/8] Only take `tcx` when it's all that's needed --- src/librustdoc/html/render/mod.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f8f71c6f3daf3..2c32fe305edab 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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}; @@ -1165,7 +1166,7 @@ fn render_deref_methods( } } -fn should_render_item(item: &clean::Item, deref_mut_: bool, cx: &Context<'_>) -> 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(), @@ -1179,7 +1180,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, cx: &Context<'_>) -> (mutability == Mutability::Mut, false, false) } SelfTy::SelfExplicit(clean::ResolvedPath { did, .. }) => { - (false, Some(did) == cx.tcx().lang_items().owned_box(), false) + (false, Some(did) == tcx.lang_items().owned_box(), false) } SelfTy::SelfValue => (false, false, true), _ => (false, false, false), @@ -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) + should_render_item(&item, deref_mut_, cx.tcx()) } }; @@ -1800,13 +1801,13 @@ fn get_methods( for_deref: bool, used_links: &mut FxHashSet, deref_mut: bool, - cx: &Context<'_>, + tcx: TyCtxt<'_>, ) -> Vec { 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, cx) { + if !for_deref || should_render_item(item, deref_mut, tcx) { Some(format!( "{}", get_next_url(used_links, format!("method.{}", name)), @@ -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, cx)) + .flat_map(move |i| { + get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx()) + }) .collect::>(); if !ret.is_empty() { // We want links' order to be reproducible so we don't use unstable sort. @@ -2001,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, cx)) + .flat_map(|i| { + get_methods(i.inner_impl(), true, &mut used_links, deref_mut, cx.tcx()) + }) .collect::>(); if !ret.is_empty() { write!( From 0bb1c285af51def917dd17ec1b1815cb34d4b208 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sun, 22 Aug 2021 18:53:00 -0700 Subject: [PATCH 3/8] rustdoc: Get symbol for `TyParam` directly --- src/librustdoc/clean/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 873ecd759ebbd..a11b9c2af8a96 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -414,7 +414,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Ty 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, From 6a84d347844afc5b228a67ac8bb147f3d0e40ddb Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 24 Aug 2021 10:33:41 -0700 Subject: [PATCH 4/8] Create a valid `Res` in `external_path()` The order of the `where` bounds on auto trait impls changed because rustdoc currently sorts auto trait `where` bounds based on the `Debug` output for the bound. Now that the bounds have an actual `Res`, they are being unintentionally sorted by their `DefId` rather than their path. So, I had to update a test for the change in ordering of the rendered bounds. --- src/librustdoc/clean/mod.rs | 19 +++++-------------- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/clean/utils.rs | 10 ++++++---- .../rustdoc/synthetic_auto/no-redundancy.rs | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e2ad21bba21b7..fc4f22ca4f480 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -166,7 +166,7 @@ impl Clean 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), + trait_ref.def_id, Some(trait_ref.def_id), true, bounds.to_vec(), @@ -1448,19 +1448,12 @@ impl<'tcx> Clean 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, None, 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, None, false, vec![], InternalSubsts::empty()); ResolvedPath { path, did, is_generic: false } } ty::Dynamic(ref obj, ref reg) => { @@ -1484,8 +1477,7 @@ impl<'tcx> Clean 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, Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, ItemType::Trait); let bound = PolyTrait { trait_: ResolvedPath { path, did, is_generic: false }, @@ -1502,8 +1494,7 @@ impl<'tcx> Clean for Ty<'tcx> { }); } - let path = - external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs); + let path = external_path(cx, did, Some(did), false, bindings, substs); bounds.insert( 0, PolyTrait { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5eff56a2200e1..8d89fae665777 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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, Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, ItemType::Trait); GenericBound::TraitBound( PolyTrait { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index a11b9c2af8a96..b6911e8886766 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -141,19 +141,21 @@ fn external_generic_args( } } -// 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 +/// 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, + did: DefId, trait_did: Option, has_self: bool, bindings: Vec, 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), diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index f727c9a47f268..16ab876e829ef 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -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 Send for Outer where T: Copy + Send" +// "impl Send for Outer where T: Send + Copy" pub struct Outer { inner_field: Inner, } From c2207f5a48376c7e4ed12975ba1130680cd57455 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 26 Aug 2021 17:47:29 -0700 Subject: [PATCH 5/8] Remove unused `hir_id` parameter from `resolve_type` --- src/librustdoc/clean/mod.rs | 10 +++++----- src/librustdoc/clean/utils.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fc4f22ca4f480..0cd7d5a1ee549 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -906,7 +906,7 @@ impl Clean for hir::IsAuto { impl Clean 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) } } @@ -1164,7 +1164,7 @@ impl Clean 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!(), @@ -1271,7 +1271,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 `::T` to a type @@ -1292,7 +1292,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) => { @@ -1308,7 +1308,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"), diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b6911e8886766..64d642884b416 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -407,8 +407,8 @@ 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)), From 5321b35a5ad037369fabae99191c9e45111b21a9 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 11 Sep 2021 15:43:44 -0700 Subject: [PATCH 6/8] Fix redundant arguments in `external_path()` If the path is for a trait, it is always true that `trait_did == Some(did)`, so instead, `external_path()` now takes an `is_trait` boolean. --- src/librustdoc/clean/mod.rs | 18 +++++---------- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/clean/utils.rs | 41 +++++++++++++++++------------------ 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0cd7d5a1ee549..81792ece8a2bb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -164,14 +164,8 @@ impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { ); } inline::record_extern_fqn(cx, trait_ref.def_id, kind); - let path = external_path( - cx, - 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, true, bounds.to_vec(), trait_ref.substs); debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); @@ -1448,12 +1442,12 @@ impl<'tcx> Clean for Ty<'tcx> { AdtKind::Enum => ItemType::Enum, }; inline::record_extern_fqn(cx, did, kind); - let path = external_path(cx, did, None, false, vec![], substs); + let path = external_path(cx, did, false, 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, did, None, false, vec![], InternalSubsts::empty()); + let path = external_path(cx, did, false, false, vec![], InternalSubsts::empty()); ResolvedPath { path, did, is_generic: false } } ty::Dynamic(ref obj, ref reg) => { @@ -1477,7 +1471,7 @@ impl<'tcx> Clean for Ty<'tcx> { for did in dids { let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, did, Some(did), false, vec![], empty); + let path = external_path(cx, did, true, false, vec![], empty); inline::record_extern_fqn(cx, did, ItemType::Trait); let bound = PolyTrait { trait_: ResolvedPath { path, did, is_generic: false }, @@ -1494,7 +1488,7 @@ impl<'tcx> Clean for Ty<'tcx> { }); } - let path = external_path(cx, did, Some(did), false, bindings, substs); + let path = external_path(cx, did, true, false, bindings, substs); bounds.insert( 0, PolyTrait { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8d89fae665777..0737ff8c6c209 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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, did, Some(did), false, vec![], empty); + let path = external_path(cx, did, true, false, vec![], empty); inline::record_extern_fqn(cx, did, ItemType::Trait); GenericBound::TraitBound( PolyTrait { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 64d642884b416..57ddf81d0e048 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -93,7 +93,8 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { fn external_generic_args( cx: &mut DocContext<'_>, - trait_did: Option, + did: DefId, + is_trait: bool, has_self: bool, bindings: Vec, substs: SubstsRef<'_>, @@ -121,32 +122,30 @@ 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 is_trait && 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 } + } else { + GenericArgs::AngleBracketed { args, bindings } } } -/// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar +/// `is_trait` should be set to `true` 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<'_>, did: DefId, - trait_did: Option, + is_trait: bool, has_self: bool, bindings: Vec, substs: SubstsRef<'_>, @@ -158,7 +157,7 @@ pub(super) fn external_path( 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, is_trait, has_self, bindings, substs), }], } } From 913764dcefb0ba69fcc1dcaa667de01273270331 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 11 Sep 2021 15:55:21 -0700 Subject: [PATCH 7/8] Remove unnecessary `is_trait` argument It was only used for sugaring `Fn` trait bounds, and rustdoc already checks that the `did` is for a `Fn` (or `FnMut`, `FnOnce`) lang item, so it's not necessary to also check that the `did` belongs to a trait. --- src/librustdoc/clean/mod.rs | 11 +++++------ src/librustdoc/clean/types.rs | 2 +- src/librustdoc/clean/utils.rs | 8 ++------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 81792ece8a2bb..84ab987062b1f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -164,8 +164,7 @@ impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { ); } inline::record_extern_fqn(cx, trait_ref.def_id, kind); - let path = - external_path(cx, trait_ref.def_id, true, 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); @@ -1442,12 +1441,12 @@ impl<'tcx> Clean for Ty<'tcx> { AdtKind::Enum => ItemType::Enum, }; inline::record_extern_fqn(cx, did, kind); - let path = external_path(cx, did, false, 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, did, false, 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) => { @@ -1471,7 +1470,7 @@ impl<'tcx> Clean for Ty<'tcx> { for did in dids { let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, did, true, 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 }, @@ -1488,7 +1487,7 @@ impl<'tcx> Clean for Ty<'tcx> { }); } - let path = external_path(cx, did, true, false, bindings, substs); + let path = external_path(cx, did, false, bindings, substs); bounds.insert( 0, PolyTrait { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0737ff8c6c209..247a6482fdcea 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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, did, true, false, vec![], empty); + let path = external_path(cx, did, false, vec![], empty); inline::record_extern_fqn(cx, did, ItemType::Trait); GenericBound::TraitBound( PolyTrait { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 57ddf81d0e048..912274c23d6cf 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -94,7 +94,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { fn external_generic_args( cx: &mut DocContext<'_>, did: DefId, - is_trait: bool, has_self: bool, bindings: Vec, substs: SubstsRef<'_>, @@ -122,7 +121,7 @@ fn external_generic_args( }) .collect(); - if is_trait && cx.tcx.fn_trait_kind_from_lang_item(did).is_some() { + 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(), @@ -140,12 +139,9 @@ fn external_generic_args( } } -/// `is_trait` should be set to `true` 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<'_>, did: DefId, - is_trait: bool, has_self: bool, bindings: Vec, substs: SubstsRef<'_>, @@ -157,7 +153,7 @@ pub(super) fn external_path( res: Res::Def(def_kind, did), segments: vec![PathSegment { name, - args: external_generic_args(cx, did, is_trait, has_self, bindings, substs), + args: external_generic_args(cx, did, has_self, bindings, substs), }], } } From 280fc2dcce6349beb46b099da8f5fbbf463185cd Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 11 Sep 2021 16:01:49 -0700 Subject: [PATCH 8/8] rustdoc: Cleanup a pattern match in `external_generic_args()` --- src/librustdoc/clean/utils.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 912274c23d6cf..b0021d1234cd6 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -122,9 +122,8 @@ fn external_generic_args( .collect(); 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(), + 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;