diff --git a/Cargo.lock b/Cargo.lock index cc1b5dcf6a7..8e1a3c57f03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4326,6 +4326,7 @@ dependencies = [ name = "rustc_metadata" version = "0.0.0" dependencies = [ + "bitflags", "libloading", "odht", "rustc_ast", diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 6d85103c9d1..bee5c8541d6 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [lib] [dependencies] +bitflags = "1.2.1" libloading = "0.7.1" odht = { version = "0.3.1", features = ["nightly"] } snap = "1" diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 143d8f2f1e1..44da3fbe300 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1594,8 +1594,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } - fn get_may_have_doc_links(self, index: DefIndex) -> bool { - self.root.tables.may_have_doc_links.get(self, index).is_some() + fn get_attr_flags(self, index: DefIndex) -> AttrFlags { + self.root.tables.attr_flags.get(self, index).unwrap_or(AttrFlags::empty()) } fn get_is_intrinsic(self, index: DefIndex) -> bool { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 6fd5bd52abe..2fa645cd9e3 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -1,6 +1,7 @@ use crate::creader::{CStore, LoadedMacro}; use crate::foreign_modules; use crate::native_libs; +use crate::rmeta::AttrFlags; use rustc_ast as ast; use rustc_attr::Deprecation; @@ -338,6 +339,7 @@ provide! { tcx, def_id, other, cdata, crate_extern_paths => { cdata.source().paths().cloned().collect() } expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) } generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) } + is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } } pub(in crate::rmeta) fn provide(providers: &mut Providers) { @@ -425,7 +427,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { return; } - if ty::util::is_doc_hidden(tcx, parent) { + if tcx.is_doc_hidden(parent) { fallback_map.push((def_id, parent)); return; } @@ -631,7 +633,9 @@ impl CStore { } pub fn may_have_doc_links_untracked(&self, def_id: DefId) -> bool { - self.get_crate_data(def_id.krate).get_may_have_doc_links(def_id.index) + self.get_crate_data(def_id.krate) + .get_attr_flags(def_id.index) + .contains(AttrFlags::MAY_HAVE_DOC_LINKS) } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 8f7a61b72f8..2ecaa33d4d3 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1111,15 +1111,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let mut is_public: Option = None; - let mut attrs = tcx - .hir() - .attrs(tcx.hir().local_def_id_to_hir_id(def_id)) + let hir_attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(def_id)); + let mut attrs = hir_attrs .iter() .filter(move |attr| should_encode_attr(tcx, attr, def_id, &mut is_public)); record_array!(self.tables.attributes[def_id.to_def_id()] <- attrs.clone()); + let mut attr_flags = AttrFlags::empty(); if attrs.any(|attr| attr.may_have_doc_links()) { - self.tables.may_have_doc_links.set(def_id.local_def_index, ()); + attr_flags |= AttrFlags::MAY_HAVE_DOC_LINKS; + } + if hir_attrs + .iter() + .filter(|attr| attr.has_name(sym::doc)) + .filter_map(|attr| attr.meta_item_list()) + .any(|items| items.iter().any(|item| item.has_name(sym::hidden))) + { + attr_flags |= AttrFlags::IS_DOC_HIDDEN; + } + if !attr_flags.is_empty() { + self.tables.attr_flags.set(def_id.local_def_index, attr_flags); } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 5066dbbb90f..69690264ae4 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -395,7 +395,7 @@ define_tables! { def_path_hashes: Table, proc_macro_quoted_spans: Table>, generator_diagnostic_data: Table>>, - may_have_doc_links: Table, + attr_flags: Table, variant_data: Table>, assoc_container: Table, // Slot is full when macro is macro_rules. @@ -418,6 +418,13 @@ struct VariantData { is_non_exhaustive: bool, } +bitflags::bitflags! { + pub struct AttrFlags: u8 { + const MAY_HAVE_DOC_LINKS = 1 << 0; + const IS_DOC_HIDDEN = 1 << 1; + } +} + // Tags used for encoding Spans: const TAG_VALID_SPAN_LOCAL: u8 = 0; const TAG_VALID_SPAN_FOREIGN: u8 = 1; @@ -440,4 +447,5 @@ trivially_parameterized_over_tcx! { IncoherentImpls, CrateRoot, CrateDep, + AttrFlags, } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 716655c7f14..dc003227d40 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -199,6 +199,20 @@ impl FixedSizeEncoding for Option { } } +impl FixedSizeEncoding for Option { + type ByteArray = [u8; 1]; + + #[inline] + fn from_bytes(b: &[u8; 1]) -> Self { + (b[0] != 0).then(|| AttrFlags::from_bits_truncate(b[0])) + } + + #[inline] + fn write_to_bytes(self, b: &mut [u8; 1]) { + b[0] = self.map_or(0, |flags| flags.bits()) + } +} + impl FixedSizeEncoding for Option<()> { type ByteArray = [u8; 1]; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6bbf7fa3914..7db86c8d0d4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1157,6 +1157,7 @@ rustc_queries! { /// Determines whether an item is annotated with `doc(hidden)`. query is_doc_hidden(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } + separate_provide_extern } /// Determines whether an item is annotated with `doc(notable_trait)`. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d0d1dcc584f..60076c8cb5f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1310,7 +1310,8 @@ pub fn reveal_opaque_types_in_bounds<'tcx>( } /// Determines whether an item is annotated with `doc(hidden)`. -pub fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool { +fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + assert!(def_id.is_local()); tcx.get_attrs(def_id, sym::doc) .filter_map(|attr| attr.meta_item_list()) .any(|items| items.iter().any(|item| item.has_name(sym::hidden))) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 87de41fde63..a020ccd53b8 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2498,14 +2498,7 @@ impl Import { } pub(crate) fn imported_item_is_doc_hidden(&self, tcx: TyCtxt<'_>) -> bool { - match self.source.did { - Some(did) => tcx - .get_attrs(did, sym::doc) - .filter_map(ast::Attribute::meta_item_list) - .flatten() - .has_word(sym::hidden), - None => false, - } + self.source.did.map_or(false, |did| tcx.is_doc_hidden(did)) } }