From 5515e2c2a106c934351382c713560c026228e232 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Oct 2022 16:15:37 +0200 Subject: [PATCH] Make rustdoc Item::visibility computed on-demand --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 29 ++----- src/librustdoc/clean/mod.rs | 64 +++------------- src/librustdoc/clean/types.rs | 84 ++++++++++++++++----- src/librustdoc/html/render/mod.rs | 12 +-- src/librustdoc/html/render/print_item.rs | 66 ++++++++-------- src/librustdoc/json/conversions.rs | 3 +- src/librustdoc/passes/strip_priv_imports.rs | 4 +- src/librustdoc/passes/strip_private.rs | 4 +- src/librustdoc/passes/stripper.rs | 19 +++-- 11 files changed, 144 insertions(+), 145 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 764a6d3aa48cf..00bdbe41ee419 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -118,7 +118,6 @@ where Some(Item { name: None, attrs: Default::default(), - visibility: Inherited, item_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, kind: Box::new(ImplItem(Box::new(Impl { unsafety: hir::Unsafety::Normal, @@ -130,6 +129,7 @@ where kind: ImplKind::Auto, }))), cfg: None, + inline_stmt_id: None, }) } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index f82fb498131eb..d80637055829d 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -97,7 +97,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { impls.push(Item { name: None, attrs: Default::default(), - visibility: Inherited, item_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, kind: Box::new(ImplItem(Box::new(Impl { unsafety: hir::Unsafety::Normal, @@ -128,6 +127,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { ))), }))), cfg: None, + inline_stmt_id: None, }); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c823ed0f16efb..4f697f9333725 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -20,7 +20,7 @@ use crate::clean::{ self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt, - ImplKind, ItemId, Type, Visibility, + ImplKind, ItemId, Type, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -152,18 +152,10 @@ pub(crate) fn try_inline( let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs); cx.inlined.insert(did.into()); - let mut item = clean::Item::from_def_id_and_attrs_and_parts( - did, - Some(name), - kind, - Box::new(attrs), - cx, - cfg, - ); - if let Some(import_def_id) = import_def_id { - // The visibility needs to reflect the one from the reexport and not from the "source" DefId. - item.visibility = clean_visibility(cx.tcx.visibility(import_def_id)); - } + let mut item = + clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg); + // The visibility needs to reflect the one from the reexport and not from the "source" DefId. + item.inline_stmt_id = import_def_id; ret.push(item); Some(ret) } @@ -239,13 +231,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean .tcx .associated_items(did) .in_definition_order() - .map(|item| { - // When building an external trait, the cleaned trait will have all items public, - // which causes methods to have a `pub` prefix, which is invalid since items in traits - // can not have a visibility prefix. Thus we override the visibility here manually. - // See https://github.com/rust-lang/rust/issues/81274 - clean::Item { visibility: Visibility::Inherited, ..clean_middle_assoc_item(item, cx) } - }) + .map(|item| clean_middle_assoc_item(item, cx)) .collect(); let predicates = cx.tcx.predicates_of(did); @@ -544,7 +530,6 @@ pub(crate) fn build_impl( }, })), Box::new(merged_attrs), - cx, cfg, )); } @@ -592,7 +577,6 @@ fn build_module_items( name: None, attrs: Box::new(clean::Attributes::default()), item_id: ItemId::Primitive(prim_ty, did.krate), - visibility: clean::Public, kind: Box::new(clean::ImportItem(clean::Import::new_simple( item.ident.name, clean::ImportSource { @@ -611,6 +595,7 @@ fn build_module_items( true, ))), cfg: None, + inline_stmt_id: None, }); } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) { items.extend(i) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8a0e6a82126bc..1ce0d1e4ffd02 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1083,10 +1083,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext TyAssocTypeItem(Box::new(generics), bounds) } }; - let what_rustc_thinks = - Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx); - // Trait items always inherit the trait's visibility -- we don't want to show `pub`. - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) }) } @@ -1117,18 +1114,7 @@ pub(crate) fn clean_impl_item<'tcx>( } }; - let mut what_rustc_thinks = - Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx); - - let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(impl_.owner_id.def_id)); - - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - if impl_ref.is_some() { - what_rustc_thinks.visibility = Inherited; - } - - what_rustc_thinks + Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx) }) } @@ -1340,18 +1326,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } }; - let mut what_rustc_thinks = - Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx); - - let impl_ref = tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)); - - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - if impl_ref.is_some() { - what_rustc_thinks.visibility = Visibility::Inherited; - } - - what_rustc_thinks + Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx) } fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { @@ -1821,23 +1796,7 @@ pub(crate) fn clean_field_with_def_id( ty: Type, cx: &mut DocContext<'_>, ) -> Item { - let what_rustc_thinks = - Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx); - if is_field_vis_inherited(cx.tcx, def_id) { - // Variant fields inherit their enum's visibility. - Item { visibility: Visibility::Inherited, ..what_rustc_thinks } - } else { - what_rustc_thinks - } -} - -fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - let parent = tcx.parent(def_id); - match tcx.def_kind(parent) { - DefKind::Struct | DefKind::Union => false, - DefKind::Variant => true, - parent_kind => panic!("unexpected parent kind: {:?}", parent_kind), - } + Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx) } pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { @@ -1861,10 +1820,7 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), }), }; - let what_rustc_thinks = - Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx); - // don't show `pub` for variants, which always inherit visibility - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx) } fn clean_variant_data<'tcx>( @@ -2038,10 +1994,7 @@ fn clean_maybe_renamed_item<'tcx>( fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item { let kind = VariantItem(clean_variant_data(&variant.data, &variant.disr_expr, cx)); - let what_rustc_thinks = - Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx); - // don't show `pub` for variants, which are always public - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx) } fn clean_impl<'tcx>( @@ -2114,6 +2067,7 @@ fn clean_extern_crate<'tcx>( } }); + let krate_owner_def_id = krate.owner_id.to_def_id(); if please_inline { let mut visited = FxHashSet::default(); @@ -2122,7 +2076,7 @@ fn clean_extern_crate<'tcx>( if let Some(items) = inline::try_inline( cx, cx.tcx.parent_module(krate.hir_id()).to_def_id(), - Some(krate.owner_id.to_def_id()), + Some(krate_owner_def_id), res, name, Some(attrs), @@ -2137,9 +2091,9 @@ fn clean_extern_crate<'tcx>( name: Some(name), attrs: Box::new(Attributes::from_ast(attrs)), item_id: crate_def_id.into(), - visibility: clean_visibility(ty_vis), kind: Box::new(ExternCrateItem { src: orig_name }), cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), + inline_stmt_id: Some(krate_owner_def_id), }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cd1f972dce844..439311f064029 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability}; use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety; use rustc_index::vec::IndexVec; use rustc_middle::ty::fast_reject::SimplifiedType; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; @@ -348,12 +348,12 @@ pub(crate) struct Item { /// Optional because not every item has a name, e.g. impls. pub(crate) name: Option, pub(crate) attrs: Box, - pub(crate) visibility: Visibility, /// Information about this item that is specific to what kind of item it is. /// E.g., struct vs enum vs function. pub(crate) kind: Box, pub(crate) item_id: ItemId, - + /// This is the `DefId` of the `use` statement if the item was inlined. + pub(crate) inline_stmt_id: Option, pub(crate) cfg: Option>, } @@ -364,9 +364,7 @@ impl fmt::Debug for Item { let alternate = f.alternate(); // hand-picked fields that don't bloat the logs too much let mut fmt = f.debug_struct("Item"); - fmt.field("name", &self.name) - .field("visibility", &self.visibility) - .field("item_id", &self.item_id); + fmt.field("name", &self.name).field("item_id", &self.item_id); // allow printing the full item if someone really wants to if alternate { fmt.field("attrs", &self.attrs).field("kind", &self.kind).field("cfg", &self.cfg); @@ -388,6 +386,15 @@ pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { )) } +fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + let parent = tcx.parent(def_id); + match tcx.def_kind(parent) { + DefKind::Struct | DefKind::Union => false, + DefKind::Variant => true, + parent_kind => panic!("unexpected parent kind: {:?}", parent_kind), + } +} + impl Item { pub(crate) fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did)) @@ -462,7 +469,6 @@ impl Item { name, kind, Box::new(Attributes::from_ast(ast_attrs)), - cx, ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } @@ -472,21 +478,18 @@ impl Item { name: Option, kind: ItemKind, attrs: Box, - cx: &mut DocContext<'_>, cfg: Option>, ) -> Item { trace!("name={:?}, def_id={:?} cfg={:?}", name, def_id, cfg); - // Primitives and Keywords are written in the source code as private modules. - // The modules need to be private so that nobody actually uses them, but the - // keywords and primitives that they are documenting are public. - let visibility = if matches!(&kind, ItemKind::KeywordItem | ItemKind::PrimitiveItem(..)) { - Visibility::Public - } else { - clean_visibility(cx.tcx.visibility(def_id)) - }; - - Item { item_id: def_id.into(), kind: Box::new(kind), name, attrs, visibility, cfg } + Item { + item_id: def_id.into(), + kind: Box::new(kind), + name, + attrs, + cfg, + inline_stmt_id: None, + } } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined @@ -702,6 +705,51 @@ impl Item { }; Some(header) } + + pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { + let def_id = match self.item_id { + // Anything but DefId *shouldn't* matter, but return a reasonable value anyway. + ItemId::Auto { .. } | ItemId::Blanket { .. } => return Visibility::Inherited, + // Primitives and Keywords are written in the source code as private modules. + // The modules need to be private so that nobody actually uses them, but the + // keywords and primitives that they are documenting are public. + ItemId::Primitive(..) => return Visibility::Public, + ItemId::DefId(def_id) => def_id, + }; + + match *self.kind { + // Explication on `ItemId::Primitive` just above. + ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Visibility::Public, + // Variant fields inherit their enum's visibility. + StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => { + return Visibility::Inherited; + } + // Variants always inherit visibility + VariantItem(..) => return Visibility::Inherited, + // Trait items inherit the trait's visibility + AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) + | TyMethodItem(..) | MethodItem(..) => { + let assoc_item = tcx.associated_item(def_id); + let is_trait_item = match assoc_item.container { + ty::TraitContainer => true, + ty::ImplContainer => { + // Trait impl items always inherit the impl's visibility -- + // we don't want to show `pub`. + tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)).is_some() + } + }; + if is_trait_item { + return Visibility::Inherited; + } + } + _ => {} + } + let def_id = match self.inline_stmt_id { + Some(inlined) => inlined, + None => def_id, + }; + clean_visibility(tcx.visibility(def_id)) + } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 27dea8ec0b312..adf501a024031 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -747,11 +747,12 @@ fn assoc_const( extra: &str, cx: &Context<'_>, ) { + let tcx = cx.tcx(); write!( w, "{extra}{vis}const {name}: {ty}", extra = extra, - vis = it.visibility.print_with_space(it.item_id, cx), + vis = it.visibility(tcx).print_with_space(it.item_id, cx), href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), ty = ty.print(cx), @@ -764,7 +765,7 @@ fn assoc_const( // This hurts readability in this context especially when more complex expressions // are involved and it doesn't add much of value. // Find a way to print constants here without all that jazz. - write!(w, "{}", Escape(&default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx())))); + write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx)))); } } @@ -805,14 +806,15 @@ fn assoc_method( cx: &Context<'_>, render_mode: RenderMode, ) { - let header = meth.fn_header(cx.tcx()).expect("Trying to get header from a non-function item"); + let tcx = cx.tcx(); + let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); - let vis = meth.visibility.print_with_space(meth.item_id, cx).to_string(); + let vis = meth.visibility(tcx).print_with_space(meth.item_id, cx).to_string(); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove // this condition. let constness = match render_mode { RenderMode::Normal => { - print_constness_with_space(&header.constness, meth.const_stability(cx.tcx())) + print_constness_with_space(&header.constness, meth.const_stability(tcx)) } RenderMode::ForDeref { .. } => "", }; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6327817364a55..13df08280b5a8 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -318,6 +318,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: ); } + let tcx = cx.tcx(); match *myitem.kind { clean::ExternCrateItem { ref src } => { use crate::html::format::anchor; @@ -327,14 +328,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: Some(src) => write!( w, "
{}extern crate {} as {};", - myitem.visibility.print_with_space(myitem.item_id, cx), + myitem.visibility(tcx).print_with_space(myitem.item_id, cx), anchor(myitem.item_id.expect_def_id(), src, cx), myitem.name.unwrap(), ), None => write!( w, "
{}extern crate {};", - myitem.visibility.print_with_space(myitem.item_id, cx), + myitem.visibility(tcx).print_with_space(myitem.item_id, cx), anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx), ), } @@ -384,7 +385,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
\ {stab_tags_before}{stab_tags}{stab_tags_after}", stab = stab.unwrap_or_default(), - vis = myitem.visibility.print_with_space(myitem.item_id, cx), + vis = myitem.visibility(tcx).print_with_space(myitem.item_id, cx), imp = import.print(cx), ); w.write_str(ITEM_TABLE_ROW_CLOSE); @@ -408,7 +409,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: let stab = myitem.stability_class(cx.tcx()); let add = if stab.is_some() { " " } else { "" }; - let visibility_emoji = match myitem.visibility { + let visibility_emoji = match myitem.visibility(tcx) { clean::Visibility::Restricted(_) => { " ðŸ”’ " } @@ -496,12 +497,13 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) -> } fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &clean::Function) { - let header = it.fn_header(cx.tcx()).expect("printing a function which isn't a function"); - let constness = print_constness_with_space(&header.constness, it.const_stability(cx.tcx())); + let tcx = cx.tcx(); + let header = it.fn_header(tcx).expect("printing a function which isn't a function"); + let constness = print_constness_with_space(&header.constness, it.const_stability(tcx)); let unsafety = header.unsafety.print_with_space(); let abi = print_abi_with_space(header.abi).to_string(); let asyncness = header.asyncness.print_with_space(); - let visibility = it.visibility.print_with_space(it.item_id, cx).to_string(); + let visibility = it.visibility(tcx).print_with_space(it.item_id, cx).to_string(); let name = it.name.unwrap(); let generics_len = format!("{:#}", f.generics.print(cx)).len(); @@ -539,6 +541,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle } fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) { + let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::>(); let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); @@ -549,8 +552,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: let count_types = required_types.len() + provided_types.len(); let count_consts = required_consts.len() + provided_consts.len(); let count_methods = required_methods.len() + provided_methods.len(); - let must_implement_one_of_functions = - cx.tcx().trait_def(t.def_id).must_implement_one_of.clone(); + let must_implement_one_of_functions = tcx.trait_def(t.def_id).must_implement_one_of.clone(); // Output the trait definition wrap_into_item_decl(w, |w| { @@ -559,9 +561,9 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: write!( w, "{}{}{}trait {}{}{}", - it.visibility.print_with_space(it.item_id, cx), - t.unsafety(cx.tcx()).print_with_space(), - if t.is_auto(cx.tcx()) { "auto " } else { "" }, + it.visibility(tcx).print_with_space(it.item_id, cx), + t.unsafety(tcx).print_with_space(), + if t.is_auto(tcx) { "auto " } else { "" }, it.name.unwrap(), t.generics.print(cx), bounds @@ -1020,7 +1022,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } let extern_crates = extern_crates .into_iter() - .map(|cnum| cx.shared.tcx.crate_name(cnum).to_string()) + .map(|cnum| tcx.crate_name(cnum).to_string()) .collect::>() .join(","); let (extern_before, extern_after) = @@ -1084,7 +1086,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { wrap_item(w, "typedef", |w| { render_attributes_in_pre(w, it, ""); - write!(w, "{}", it.visibility.print_with_space(it.item_id, cx)); + write!(w, "{}", it.visibility(cx.tcx()).print_with_space(it.item_id, cx)); write!( w, "type {}{}{where_clause} = {type_};", @@ -1173,6 +1175,7 @@ fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item] } fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) { + let tcx = cx.tcx(); let count_variants = e.variants().count(); wrap_into_item_decl(w, |w| { wrap_item(w, "enum", |w| { @@ -1180,7 +1183,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!( w, "{}enum {}{}", - it.visibility.print_with_space(it.item_id, cx), + it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(), e.generics.print(cx), ); @@ -1268,10 +1271,10 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w.write_str(""); render_stability_since_raw( w, - variant.stable_since(cx.tcx()), - variant.const_stability(cx.tcx()), - it.stable_since(cx.tcx()), - it.const_stable_since(cx.tcx()), + variant.stable_since(tcx), + variant.const_stability(tcx), + it.stable_since(tcx), + it.const_stable_since(tcx), ); w.write_str(""); @@ -1389,12 +1392,13 @@ fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) { wrap_into_item_decl(w, |w| { wrap_item(w, "const", |w| { + let tcx = cx.tcx(); render_attributes_in_code(w, it); write!( w, "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(it.item_id, cx), + vis = it.visibility(tcx).print_with_space(it.item_id, cx), name = it.name.unwrap(), typ = c.type_.print(cx), ); @@ -1408,9 +1412,9 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle // ` = 100i32;` // instead? - let value = c.value(cx.tcx()); - let is_literal = c.is_literal(cx.tcx()); - let expr = c.expr(cx.tcx()); + let value = c.value(tcx); + let is_literal = c.is_literal(tcx); + let expr = c.expr(tcx); if value.is_some() || is_literal { write!(w, " = {expr};", expr = Escape(&expr)); } else { @@ -1495,7 +1499,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean write!( w, "{vis}static {mutability}{name}: {typ}", - vis = it.visibility.print_with_space(it.item_id, cx), + vis = it.visibility(cx.tcx()).print_with_space(it.item_id, cx), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) @@ -1513,7 +1517,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { write!( w, " {}type {};\n}}", - it.visibility.print_with_space(it.item_id, cx), + it.visibility(cx.tcx()).print_with_space(it.item_id, cx), it.name.unwrap(), ); }); @@ -1666,7 +1670,8 @@ fn render_union( tab: &str, cx: &Context<'_>, ) { - write!(w, "{}union {}", it.visibility.print_with_space(it.item_id, cx), it.name.unwrap(),); + let tcx = cx.tcx(); + write!(w, "{}union {}", it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(),); let where_displayed = g .map(|g| { @@ -1693,7 +1698,7 @@ fn render_union( write!( w, " {}{}: {},\n{}", - field.visibility.print_with_space(field.item_id, cx), + field.visibility(tcx).print_with_space(field.item_id, cx), field.name.unwrap(), ty.print(cx), tab @@ -1720,10 +1725,11 @@ fn render_struct( structhead: bool, cx: &Context<'_>, ) { + let tcx = cx.tcx(); write!( w, "{}{}{}", - it.visibility.print_with_space(it.item_id, cx), + it.visibility(tcx).print_with_space(it.item_id, cx), if structhead { "struct " } else { "" }, it.name.unwrap() ); @@ -1753,7 +1759,7 @@ fn render_struct( w, "\n{} {}{}: {},", tab, - field.visibility.print_with_space(field.item_id, cx), + field.visibility(tcx).print_with_space(field.item_id, cx), field.name.unwrap(), ty.print(cx), ); @@ -1785,7 +1791,7 @@ fn render_struct( write!( w, "{}{}", - field.visibility.print_with_space(field.item_id, cx), + field.visibility(tcx).print_with_space(field.item_id, cx), ty.print(cx), ) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index cdf59cdd32845..4962eb8f8e176 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -48,7 +48,8 @@ impl JsonRenderer<'_> { .map(rustc_ast_pretty::pprust::attribute_to_string) .collect(); let span = item.span(self.tcx); - let clean::Item { name, attrs: _, kind: _, visibility, item_id, cfg: _ } = item; + let visibility = item.visibility(self.tcx); + let clean::Item { name, attrs: _, kind: _, item_id, cfg: _, .. } = item; let inner = match *item.kind { clean::KeywordItem => return None, clean::StrippedItem(ref inner) => { diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index 85be8fa109a7e..3bac5a8e5d749 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -11,6 +11,6 @@ pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass { description: "strips all private import statements (`use`, `extern crate`) from a crate", }; -pub(crate) fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate { - ImportStripper.fold_crate(krate) +pub(crate) fn strip_priv_imports(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + ImportStripper { tcx: cx.tcx }.fold_crate(krate) } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index e3b958b2036e3..8fc42462de969 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -22,13 +22,13 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> // strip all private items { let mut stripper = Stripper { - tcx: cx.tcx, retained: &mut retained, effective_visibilities: &cx.cache.effective_visibilities, update_retained: true, is_json_output, + tcx: cx.tcx, }; - krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); + krate = ImportStripper { tcx: cx.tcx }.fold_crate(stripper.fold_crate(krate)); } // strip all impls referencing private items diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 4fa5c04ddf61d..b2047360ccd9a 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -2,7 +2,6 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; - use std::mem; use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt}; @@ -11,11 +10,11 @@ use crate::formats::cache::Cache; use crate::visit_lib::RustdocEffectiveVisibilities; pub(crate) struct Stripper<'a, 'tcx> { - pub(crate) tcx: TyCtxt<'tcx>, pub(crate) retained: &'a mut ItemIdSet, pub(crate) effective_visibilities: &'a RustdocEffectiveVisibilities, pub(crate) update_retained: bool, pub(crate) is_json_output: bool, + pub(crate) tcx: TyCtxt<'tcx>, } // We need to handle this differently for the JSON output because some non exported items could @@ -35,7 +34,7 @@ fn is_item_reachable( } } -impl<'a> DocFolder for Stripper<'a, '_> { +impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { clean::StrippedItem(..) => { @@ -82,13 +81,13 @@ impl<'a> DocFolder for Stripper<'a, '_> { } clean::StructFieldItem(..) => { - if !i.visibility.is_public() { + if !i.visibility(self.tcx).is_public() { return Some(strip_item(i)); } } clean::ModuleItem(..) => { - if i.item_id.is_local() && !i.visibility.is_public() { + if i.item_id.is_local() && !i.visibility(self.tcx).is_public() { debug!("Stripper: stripping module {:?}", i.name); let old = mem::replace(&mut self.update_retained, false); let ret = strip_item(self.fold_item_recur(i)); @@ -239,12 +238,16 @@ impl<'a> DocFolder for ImplStripper<'a, '_> { } /// This stripper discards all private import statements (`use`, `extern crate`) -pub(crate) struct ImportStripper; +pub(crate) struct ImportStripper<'tcx> { + pub(crate) tcx: TyCtxt<'tcx>, +} -impl DocFolder for ImportStripper { +impl<'tcx> DocFolder for ImportStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { - clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => { + clean::ExternCrateItem { .. } | clean::ImportItem(..) + if !i.visibility(self.tcx).is_public() => + { None } _ => Some(self.fold_item_recur(i)),