From 4ad14acc171136d01bc0fb615e29eb14d97d789e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 30 Nov 2021 21:42:54 +0000 Subject: [PATCH] Calculate visibility on-demand, not up-front - lots of staring really hard at the existing code to make sure the behavior matches - store `inline_stmt_id` and `crate_stmt_id` to be able to get their visibility (rustdoc stores the IDs of the item definition in `clean::Item`, not the re-export) --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 26 ++------- src/librustdoc/clean/mod.rs | 65 +++++++-------------- src/librustdoc/clean/types.rs | 57 +++++++++++++----- src/librustdoc/fold.rs | 2 +- src/librustdoc/html/render/mod.rs | 4 +- src/librustdoc/html/render/print_item.rs | 34 ++++++----- src/librustdoc/json/conversions.rs | 5 +- src/librustdoc/passes/strip_priv_imports.rs | 4 +- src/librustdoc/passes/strip_private.rs | 3 +- src/librustdoc/passes/stripper.rs | 18 +++--- src/librustdoc/visit.rs | 2 +- 13 files changed, 111 insertions(+), 113 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 04fe1dccce44b..bbbb83182b31a 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -112,7 +112,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { Some(Item { name: None, attrs: Default::default(), - visibility: Inherited, def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, @@ -124,6 +123,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { 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 f44589f60675f..cca77625ef74b 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -103,7 +103,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { impls.push(Item { name: None, attrs: Default::default(), - visibility: Inherited, def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, @@ -127,6 +126,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { kind: ImplKind::Blanket(box trait_ref.self_ty().clean(self.cx)), }), cfg: None, + inline_stmt_id: None, }); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ba67030d59fb0..6b3f3058415bd 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -20,7 +20,7 @@ use crate::clean::{ use crate::core::DocContext; use crate::formats::item_type::ItemType; -use super::{Clean, Visibility}; +use super::Clean; type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>; @@ -125,11 +125,8 @@ crate fn try_inline( let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone); cx.inlined.insert(did.into()); let mut item = - clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box 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 = cx.tcx.visibility(import_def_id).clean(cx); - } + clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box attrs, cfg); + item.inline_stmt_id = import_def_id; ret.push(item); Some(ret) } @@ -194,18 +191,8 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) } crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { - let trait_items = cx - .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, ..item.clean(cx) } - }) - .collect(); + let trait_items = + cx.tcx.associated_items(did).in_definition_order().map(|item| item.clean(cx)).collect(); let predicates = cx.tcx.predicates_of(did); let generics = (cx.tcx.generics_of(did), predicates).clean(cx); @@ -497,7 +484,6 @@ crate fn build_impl( kind: ImplKind::Normal, }), box merged_attrs, - cx, cfg, )); } @@ -527,7 +513,6 @@ fn build_module( name: None, attrs: box clean::Attributes::default(), def_id: ItemId::Primitive(prim_ty, did.krate), - visibility: clean::Public, kind: box clean::ImportItem(clean::Import::new_simple( item.ident.name, clean::ImportSource { @@ -546,6 +531,7 @@ fn build_module( 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 9b05716a67bc2..2250015dbadc8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -909,10 +909,7 @@ impl Clean for hir::TraitItem<'_> { AssocTypeItem(bounds, default) } }; - let what_rustc_thinks = - Item::from_def_id_and_parts(local_did, Some(self.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(self.ident.name), inner, cx) }) } } @@ -948,20 +945,7 @@ impl Clean for hir::ImplItem<'_> { } }; - let what_rustc_thinks = - Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx); - let parent_item = cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_did(self.hir_id())); - if let hir::ItemKind::Impl(impl_) = &parent_item.kind { - if impl_.of_trait.is_some() { - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - Item { visibility: Inherited, ..what_rustc_thinks } - } else { - what_rustc_thinks - } - } else { - panic!("found impl item with non-impl parent {:?}", parent_item); - } + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) }) } } @@ -1570,14 +1554,7 @@ impl Clean for ty::FieldDef { } fn clean_field(def_id: DefId, name: Symbol, 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 - } + Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx) } fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { @@ -1592,17 +1569,21 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } +fn clean_vis(vis: ty::Visibility) -> Visibility { + match vis { + ty::Visibility::Public => Visibility::Public, + // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private', + // while rustdoc really does mean inherited. That means that for enum variants, such as + // `pub enum E { V }`, `V` will be marked as `Public` by `ty`, but as `Inherited` by rustdoc. + // `Item::visibility()` overrides `tcx.visibility` explicitly to make sure this distinction is captured. + ty::Visibility::Invisible => Visibility::Inherited, + ty::Visibility::Restricted(module) => Visibility::Restricted(module), + } +} + impl Clean for ty::Visibility { fn clean(&self, _cx: &mut DocContext<'_>) -> Visibility { - match *self { - ty::Visibility::Public => Visibility::Public, - // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private', - // while rustdoc really does mean inherited. That means that for enum variants, such as - // `pub enum E { V }`, `V` will be marked as `Public` by `ty`, but as `Inherited` by rustdoc. - // Various parts of clean override `tcx.visibility` explicitly to make sure this distinction is captured. - ty::Visibility::Invisible => Visibility::Inherited, - ty::Visibility::Restricted(module) => Visibility::Restricted(module), - } + clean_vis(*self) } } @@ -1635,10 +1616,7 @@ impl Clean for ty::VariantDef { fields: self.fields.iter().map(|field| field.clean(cx)).collect(), }), }; - 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 variants, which always inherit visibility - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_def_id_and_parts(self.def_id, Some(self.ident.name), VariantItem(kind), cx) } } @@ -1798,10 +1776,7 @@ impl Clean> for (&hir::Item<'_>, Option) { impl Clean for hir::Variant<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> Item { 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 - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx) } } @@ -1887,9 +1862,9 @@ fn clean_extern_crate( name: Some(name), attrs: box attrs.clean(cx), def_id: crate_def_id.into(), - visibility: ty_vis.clean(cx), - kind: box ExternCrateItem { src: orig_name }, + kind: box ExternCrateItem { src: orig_name, crate_stmt_id: krate.def_id }, cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), + inline_stmt_id: None, }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 37acf68defd25..58c8b394ffe64 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -18,7 +18,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_hir::{BodyId, Mutability}; use rustc_index::vec::IndexVec; @@ -32,10 +32,10 @@ use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; use crate::clean::cfg::Cfg; -use crate::clean::external_path; use crate::clean::inline::{self, print_inlined_const}; use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const}; use crate::clean::Clean; +use crate::clean::{external_path, is_field_vis_inherited}; use crate::core::DocContext; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; @@ -348,12 +348,12 @@ crate struct Item { /// Optional because not every item has a name, e.g. impls. crate name: Option, crate attrs: Box, - crate visibility: Visibility, /// Information about this item that is specific to what kind of item it is. /// E.g., struct vs enum vs function. crate kind: Box, crate def_id: ItemId, - + /// If this item was inlined, the DefId of the `use` statement. + crate inline_stmt_id: Option, crate cfg: Option>, } @@ -388,6 +388,42 @@ impl Item { self.def_id.as_def_id().map(|did| tcx.get_attrs(did).inner_docs()).unwrap_or(false) } + crate fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { + let mut def_id = match self.def_id { + // Anything but DefId *shouldn't* matter, but return a reasonable value anyway. + ItemId::Auto { .. } | ItemId::Blanket { .. } => return Visibility::Inherited, + ItemId::Primitive(..) => return Visibility::Public, + ItemId::DefId(did) => did, + }; + match *self.kind { + // 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, + // Return the visibility of `extern crate` statement, not the crate itself (which will always be public). + ExternCrateItem { crate_stmt_id, .. } => def_id = crate_stmt_id.to_def_id(), + // Trait items inherit the trait's visibility + AssocConstItem(..) | AssocTypeItem(..) | TyMethodItem(..) | MethodItem(..) => { + let is_trait_item = match tcx.associated_item(def_id).container { + ty::TraitContainer(_) => true, + ty::ImplContainer(impl_id) => tcx.impl_trait_ref(impl_id).is_some(), + }; + if is_trait_item { + return Visibility::Inherited; + } + } + _ => {} + } + // If this item was inlined, show the visibility of the `use` statement, not the definition. + let def_id = match self.inline_stmt_id { + Some(inlined) => inlined, + None => def_id, + }; + super::clean_vis(tcx.visibility(def_id)) + } + crate fn span(&self, tcx: TyCtxt<'_>) -> Span { let kind = match &*self.kind { ItemKind::StrippedItem(k) => k, @@ -443,7 +479,6 @@ impl Item { name, kind, box ast_attrs.clean(cx), - cx, ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } @@ -453,19 +488,11 @@ impl Item { name: Option, kind: ItemKind, attrs: Box, - cx: &mut DocContext<'_>, cfg: Option>, ) -> Item { trace!("name={:?}, def_id={:?}", name, def_id); - Item { - def_id: def_id.into(), - kind: box kind, - name, - attrs, - visibility: cx.tcx.visibility(def_id).clean(cx), - cfg, - } + Item { def_id: def_id.into(), kind: box kind, name, attrs, cfg, inline_stmt_id: None } } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined @@ -640,6 +667,8 @@ crate enum ItemKind { ExternCrateItem { /// The crate's name, *not* the name it's imported as. src: Option, + /// The id of the `extern crate` statement, not the crate itself. + crate_stmt_id: LocalDefId, }, ImportItem(Import), StructItem(Struct), diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index cd0f44e5696fe..aaffa07ac9681 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -68,7 +68,7 @@ crate trait DocFolder: Sized { } Variant::CLike => VariantItem(Variant::CLike), }, - ExternCrateItem { src: _ } + ExternCrateItem { .. } | ImportItem(_) | FunctionItem(_) | TypedefItem(_, _) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 08022d526fefb..96da5cbd97436 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -771,7 +771,7 @@ fn assoc_const( w, "{}{}const {}: {}", extra, - it.visibility.print_with_space(it.def_id, cx), + it.visibility(cx.tcx()).print_with_space(it.def_id, cx), naive_assoc_href(it, link, cx), it.name.as_ref().unwrap(), ty.print(cx) @@ -892,7 +892,7 @@ fn render_assoc_item( } } }; - let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string(); + let vis = meth.visibility(cx.tcx()).print_with_space(meth.def_id, cx).to_string(); let constness = print_constness_with_space(&header.constness, meth.const_stability(cx.tcx())); let asyncness = header.asyncness.print_with_space(); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d3738cfa3e781..b6db1c228b7a4 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -306,22 +306,23 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl } match *myitem.kind { - clean::ExternCrateItem { ref src } => { + clean::ExternCrateItem { ref src, crate_stmt_id: _ } => { use crate::html::format::anchor; + let vis = myitem.visibility(cx.tcx()).print_with_space(myitem.def_id, cx); w.write_str(ITEM_TABLE_ROW_OPEN); match *src { Some(ref src) => write!( w, "
{}extern crate {} as {};", - myitem.visibility.print_with_space(myitem.def_id, cx), + vis, anchor(myitem.def_id.expect_def_id(), &*src.as_str(), cx), myitem.name.as_ref().unwrap(), ), None => write!( w, "
{}extern crate {};", - myitem.visibility.print_with_space(myitem.def_id, cx), + vis, anchor( myitem.def_id.expect_def_id(), &*myitem.name.as_ref().unwrap().as_str(), @@ -354,6 +355,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl }; let add = if stab.is_some() { " " } else { "" }; + let vis = myitem.visibility(cx.tcx()).print_with_space(myitem.def_id, cx); w.write_str(ITEM_TABLE_ROW_OPEN); write!( @@ -364,7 +366,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
{stab_tags}
", stab = stab.unwrap_or_default(), add = add, - vis = myitem.visibility.print_with_space(myitem.def_id, cx), + vis = vis, imp = import.print(cx), stab_tags = stab_tags.unwrap_or_default(), ); @@ -465,7 +467,7 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) -> } fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { - let vis = it.visibility.print_with_space(it.def_id, cx).to_string(); + let vis = it.visibility(cx.tcx()).print_with_space(it.def_id, cx).to_string(); let constness = print_constness_with_space(&f.header.constness, it.const_stability(cx.tcx())); let asyncness = f.header.asyncness.print_with_space(); let unsafety = f.header.unsafety.print_with_space(); @@ -523,7 +525,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write!( w, "{}{}{}trait {}{}{}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility(cx.tcx()).print_with_space(it.def_id, cx), t.unsafety.print_with_space(), if t.is_auto { "auto " } else { "" }, it.name.as_ref().unwrap(), @@ -911,7 +913,7 @@ fn item_typedef( wrap_item(w, "typedef", |w| { render_attributes_in_pre(w, it, ""); if !is_associated { - write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); + write!(w, "{}", it.visibility(cx.tcx()).print_with_space(it.def_id, cx)); } write!( w, @@ -1012,7 +1014,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum write!( w, "{}enum {}{}{}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility(cx.tcx()).print_with_space(it.def_id, cx), it.name.as_ref().unwrap(), e.generics.print(cx), print_where_clause(&e.generics, cx, 0, true), @@ -1209,7 +1211,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean:: write!( w, "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), + vis = it.visibility(cx.tcx()).print_with_space(it.def_id, cx), name = it.name.as_ref().unwrap(), typ = c.type_.print(cx), ); @@ -1301,7 +1303,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St write!( w, "{vis}static {mutability}{name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), + vis = it.visibility(cx.tcx()).print_with_space(it.def_id, cx), mutability = s.mutability.print_with_space(), name = it.name.as_ref().unwrap(), typ = s.type_.print(cx) @@ -1319,7 +1321,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { write!( w, " {}type {};\n}}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility(cx.tcx()).print_with_space(it.def_id, cx), it.name.as_ref().unwrap(), ); }); @@ -1491,7 +1493,7 @@ fn render_union( write!( w, "{}union {}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility(cx.tcx()).print_with_space(it.def_id, cx), it.name.as_ref().unwrap() ); if let Some(g) = g { @@ -1512,7 +1514,7 @@ fn render_union( write!( w, " {}{}: {},\n{}", - field.visibility.print_with_space(field.def_id, cx), + field.visibility(cx.tcx()).print_with_space(field.def_id, cx), field.name.as_ref().unwrap(), ty.print(cx), tab @@ -1542,7 +1544,7 @@ fn render_struct( write!( w, "{}{}{}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility(cx.tcx()).print_with_space(it.def_id, cx), if structhead { "struct " } else { "" }, it.name.as_ref().unwrap() ); @@ -1568,7 +1570,7 @@ fn render_struct( w, "\n{} {}{}: {},", tab, - field.visibility.print_with_space(field.def_id, cx), + field.visibility(cx.tcx()).print_with_space(field.def_id, cx), field.name.as_ref().unwrap(), ty.print(cx), ); @@ -1602,7 +1604,7 @@ fn render_struct( write!( w, "{}{}", - field.visibility.print_with_space(field.def_id, cx), + field.visibility(cx.tcx()).print_with_space(field.def_id, cx), ty.print(cx), ) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7fc295747f41a..ec284dcbcb05c 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -40,7 +40,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, def_id, cfg: _ } = item; + let visibility = item.visibility(self.tcx); + let clean::Item { name, attrs: _, kind: _, def_id, cfg: _, inline_stmt_id: _ } = item; let inner = match *item.kind { clean::StrippedItem(_) => return None, _ => from_clean_item(item, self.tcx), @@ -229,7 +230,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { KeywordItem(_) => { panic!("{:?} is not supported for JSON output", item) } - ExternCrateItem { ref src } => ItemEnum::ExternCrate { + ExternCrateItem { ref src, crate_stmt_id: _ } => ItemEnum::ExternCrate { name: name.as_ref().unwrap().to_string(), rename: src.map(|x| x.to_string()), }, diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index 63869324cb8d2..a7ee0c91a80d0 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -9,6 +9,6 @@ crate const STRIP_PRIV_IMPORTS: Pass = Pass { description: "strips all private import statements (`use`, `extern crate`) from a crate", }; -crate fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate { - ImportStripper.fold_crate(krate) +crate fn strip_priv_imports(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + ImportStripper(cx.tcx).fold_crate(krate) } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index dfdba2a4b3666..f33ac91f113d4 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -22,8 +22,9 @@ crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clea retained: &mut retained, access_levels: &cx.cache.access_levels, update_retained: true, + tcx: cx.tcx, }; - krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); + krate = ImportStripper(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 74a9a2da06d36..827061d33ffd7 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -1,17 +1,19 @@ use rustc_hir::def_id::DefId; use rustc_middle::middle::privacy::AccessLevels; +use rustc_middle::ty::TyCtxt; use std::mem; use crate::clean::{self, Item, ItemIdSet}; use crate::fold::{strip_item, DocFolder}; -crate struct Stripper<'a> { +crate struct Stripper<'a, 'tcx> { crate retained: &'a mut ItemIdSet, crate access_levels: &'a AccessLevels, crate update_retained: bool, + pub(super) tcx: TyCtxt<'tcx>, } -impl<'a> DocFolder for Stripper<'a> { +impl DocFolder for Stripper<'_, '_> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { clean::StrippedItem(..) => { @@ -51,13 +53,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.def_id.is_local() && !i.visibility.is_public() { + if i.def_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)); @@ -158,12 +160,14 @@ impl<'a> DocFolder for ImplStripper<'a> { } /// This stripper discards all private import statements (`use`, `extern crate`) -crate struct ImportStripper; +crate struct ImportStripper<'tcx>(pub(super) TyCtxt<'tcx>); -impl DocFolder for ImportStripper { +impl DocFolder for ImportStripper<'_> { 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.0).is_public() => + { None } _ => Some(self.fold_item_recur(i)), diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index df4d1558ebdf4..f03c3328723ff 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -23,7 +23,7 @@ crate trait DocVisitor: Sized { Variant::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)), Variant::CLike => {} }, - ExternCrateItem { src: _ } + ExternCrateItem { .. } | ImportItem(_) | FunctionItem(_) | TypedefItem(_, _)