Skip to content

Commit 415c141

Browse files
committed
rustc_metadata: Encode doc(hidden) flag to metadata
To retrieve these flags rustdoc currently has to mass decode full attributes for items in the whole crate tree, so it's better to pre-compute it in advance. This is especially for short-term performance of rust-lang#107054 because resolver cannot use memoization of query results yet.
1 parent 005fc0f commit 415c141

File tree

10 files changed

+52
-18
lines changed

10 files changed

+52
-18
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4326,6 +4326,7 @@ dependencies = [
43264326
name = "rustc_metadata"
43274327
version = "0.0.0"
43284328
dependencies = [
4329+
"bitflags",
43294330
"libloading",
43304331
"odht",
43314332
"rustc_ast",

compiler/rustc_metadata/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
[lib]
77

88
[dependencies]
9+
bitflags = "1.2.1"
910
libloading = "0.7.1"
1011
odht = { version = "0.3.1", features = ["nightly"] }
1112
snap = "1"

compiler/rustc_metadata/src/rmeta/decoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1594,8 +1594,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
15941594
})
15951595
}
15961596

1597-
fn get_may_have_doc_links(self, index: DefIndex) -> bool {
1598-
self.root.tables.may_have_doc_links.get(self, index).is_some()
1597+
fn get_attr_flags(self, index: DefIndex) -> AttrFlags {
1598+
self.root.tables.attr_flags.get(self, index).unwrap_or(AttrFlags::empty())
15991599
}
16001600

16011601
fn get_is_intrinsic(self, index: DefIndex) -> bool {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::creader::{CStore, LoadedMacro};
22
use crate::foreign_modules;
33
use crate::native_libs;
4+
use crate::rmeta::AttrFlags;
45

56
use rustc_ast as ast;
67
use rustc_attr::Deprecation;
@@ -338,6 +339,7 @@ provide! { tcx, def_id, other, cdata,
338339
crate_extern_paths => { cdata.source().paths().cloned().collect() }
339340
expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
340341
generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) }
342+
is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) }
341343
}
342344

343345
pub(in crate::rmeta) fn provide(providers: &mut Providers) {
@@ -425,7 +427,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
425427
return;
426428
}
427429

428-
if ty::util::is_doc_hidden(tcx, parent) {
430+
if tcx.is_doc_hidden(parent) {
429431
fallback_map.push((def_id, parent));
430432
return;
431433
}
@@ -631,7 +633,9 @@ impl CStore {
631633
}
632634

633635
pub fn may_have_doc_links_untracked(&self, def_id: DefId) -> bool {
634-
self.get_crate_data(def_id.krate).get_may_have_doc_links(def_id.index)
636+
self.get_crate_data(def_id.krate)
637+
.get_attr_flags(def_id.index)
638+
.contains(AttrFlags::MAY_HAVE_DOC_LINKS)
635639
}
636640
}
637641

compiler/rustc_metadata/src/rmeta/encoder.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -1111,15 +1111,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
11111111
let tcx = self.tcx;
11121112
let mut is_public: Option<bool> = None;
11131113

1114-
let mut attrs = tcx
1115-
.hir()
1116-
.attrs(tcx.hir().local_def_id_to_hir_id(def_id))
1114+
let hir_attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(def_id));
1115+
let mut attrs = hir_attrs
11171116
.iter()
11181117
.filter(move |attr| should_encode_attr(tcx, attr, def_id, &mut is_public));
11191118

11201119
record_array!(self.tables.attributes[def_id.to_def_id()] <- attrs.clone());
1120+
let mut attr_flags = AttrFlags::empty();
11211121
if attrs.any(|attr| attr.may_have_doc_links()) {
1122-
self.tables.may_have_doc_links.set(def_id.local_def_index, ());
1122+
attr_flags |= AttrFlags::MAY_HAVE_DOC_LINKS;
1123+
}
1124+
if hir_attrs
1125+
.iter()
1126+
.filter(|attr| attr.has_name(sym::doc))
1127+
.filter_map(|attr| attr.meta_item_list())
1128+
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
1129+
{
1130+
attr_flags |= AttrFlags::IS_DOC_HIDDEN;
1131+
}
1132+
if !attr_flags.is_empty() {
1133+
self.tables.attr_flags.set(def_id.local_def_index, attr_flags);
11231134
}
11241135
}
11251136

compiler/rustc_metadata/src/rmeta/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ define_tables! {
395395
def_path_hashes: Table<DefIndex, DefPathHash>,
396396
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
397397
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
398-
may_have_doc_links: Table<DefIndex, ()>,
398+
attr_flags: Table<DefIndex, AttrFlags>,
399399
variant_data: Table<DefIndex, LazyValue<VariantData>>,
400400
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
401401
// Slot is full when macro is macro_rules.
@@ -418,6 +418,13 @@ struct VariantData {
418418
is_non_exhaustive: bool,
419419
}
420420

421+
bitflags::bitflags! {
422+
pub struct AttrFlags: u8 {
423+
const MAY_HAVE_DOC_LINKS = 1 << 0;
424+
const IS_DOC_HIDDEN = 1 << 1;
425+
}
426+
}
427+
421428
// Tags used for encoding Spans:
422429
const TAG_VALID_SPAN_LOCAL: u8 = 0;
423430
const TAG_VALID_SPAN_FOREIGN: u8 = 1;
@@ -440,4 +447,5 @@ trivially_parameterized_over_tcx! {
440447
IncoherentImpls,
441448
CrateRoot,
442449
CrateDep,
450+
AttrFlags,
443451
}

compiler/rustc_metadata/src/rmeta/table.rs

+14
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,20 @@ impl FixedSizeEncoding for Option<RawDefId> {
199199
}
200200
}
201201

202+
impl FixedSizeEncoding for Option<AttrFlags> {
203+
type ByteArray = [u8; 1];
204+
205+
#[inline]
206+
fn from_bytes(b: &[u8; 1]) -> Self {
207+
(b[0] != 0).then(|| AttrFlags::from_bits_truncate(b[0]))
208+
}
209+
210+
#[inline]
211+
fn write_to_bytes(self, b: &mut [u8; 1]) {
212+
b[0] = self.map_or(0, |flags| flags.bits())
213+
}
214+
}
215+
202216
impl FixedSizeEncoding for Option<()> {
203217
type ByteArray = [u8; 1];
204218

compiler/rustc_middle/src/query/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,7 @@ rustc_queries! {
11571157
/// Determines whether an item is annotated with `doc(hidden)`.
11581158
query is_doc_hidden(def_id: DefId) -> bool {
11591159
desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) }
1160+
separate_provide_extern
11601161
}
11611162

11621163
/// Determines whether an item is annotated with `doc(notable_trait)`.

compiler/rustc_middle/src/ty/util.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,8 @@ pub fn reveal_opaque_types_in_bounds<'tcx>(
13101310
}
13111311

13121312
/// Determines whether an item is annotated with `doc(hidden)`.
1313-
pub fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
1313+
fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
1314+
assert!(def_id.is_local());
13141315
tcx.get_attrs(def_id, sym::doc)
13151316
.filter_map(|attr| attr.meta_item_list())
13161317
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))

src/librustdoc/clean/types.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -2498,14 +2498,7 @@ impl Import {
24982498
}
24992499

25002500
pub(crate) fn imported_item_is_doc_hidden(&self, tcx: TyCtxt<'_>) -> bool {
2501-
match self.source.did {
2502-
Some(did) => tcx
2503-
.get_attrs(did, sym::doc)
2504-
.filter_map(ast::Attribute::meta_item_list)
2505-
.flatten()
2506-
.has_word(sym::hidden),
2507-
None => false,
2508-
}
2501+
self.source.did.map_or(false, |did| tcx.is_doc_hidden(did))
25092502
}
25102503
}
25112504

0 commit comments

Comments
 (0)