diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c1bba0b01975e..544d484d6dd16 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -963,6 +963,11 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let incremental = dep_graph.is_fully_enabled(); + // is_doc_hidden hook is reset to query call for incremental build (fallback for optimization) + if incremental { + providers.hooks.is_doc_hidden = |tcx, def_id| tcx.is_doc_hidden_q(def_id); + } + let gcx_cell = OnceLock::new(); let arena = WorkerLocal::new(|_| Arena::default()); let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default()); diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index df3add316ec23..f2748fce3547b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use rustc_hir::attrs::Deprecation; use rustc_hir::def::{CtorKind, DefKind}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::bug; @@ -18,7 +18,7 @@ use rustc_middle::util::Providers; use rustc_session::cstore::{CrateStore, ExternCrate}; use rustc_session::{Session, StableCrateId}; use rustc_span::hygiene::ExpnId; -use rustc_span::{Span, Symbol, kw}; +use rustc_span::{Span, Symbol, kw, sym}; use super::{Decodable, DecodeContext, DecodeIterator}; use crate::creader::{CStore, LoadedMacro}; @@ -396,7 +396,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) } default_field => { cdata.get_default_field(def_id.index) } - is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } + is_doc_hidden_q => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(def_id.index)) } doc_link_traits_in_scope => { tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(def_id.index)) @@ -679,6 +679,29 @@ impl CrateStore for CStore { } } +/// Determines whether an item is directly annotated with `doc(hidden)`. +fn is_doc_hidden_local(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + 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))) +} + +// Optimization of is_doc_hidden query in case of non-incremental build. +// is_doc_hidden query itself renamed into is_doc_hidden_q. +#[inline] +fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + if let Some(local) = def_id.as_local() { + is_doc_hidden_local(tcx, local) + } else { + let cdata = rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx(tcx), |c| { + c.get_crate_data(def_id.krate).cdata + }); + let cdata = + crate::creader::CrateMetadataRef { cdata: &cdata, cstore: &CStore::from_tcx(tcx) }; + cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) + } +} + fn provide_cstore_hooks(providers: &mut Providers) { providers.hooks.def_path_hash_to_def_id_extern = |tcx, hash, stable_crate_id| { // If this is a DefPathHash from an upstream crate, let the CrateStore map @@ -706,4 +729,6 @@ fn provide_cstore_hooks(providers: &mut Providers) { cdata.imported_source_file(file_index as u32, tcx.sess); } }; + providers.hooks.is_doc_hidden = is_doc_hidden; + providers.is_doc_hidden_q = is_doc_hidden_local; } diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index dc6a3334a4c8b..7e86e74ce041b 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -102,6 +102,9 @@ declare_hooks! { /// Ensure the given scalar is valid for the given type. /// This checks non-recursive runtime validity. hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool; + + /// Determines whether an item is annotated with `#[doc(hidden)]`. + hook is_doc_hidden(def_id: DefId) -> bool; } #[cold] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 895c8c0295a04..c5044ca07da00 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1511,7 +1511,7 @@ rustc_queries! { } /// Determines whether an item is annotated with `#[doc(hidden)]`. - query is_doc_hidden(def_id: DefId) -> bool { + query is_doc_hidden_q(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index a4422abc6883a..8f2743ec0b143 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1662,13 +1662,6 @@ pub fn reveal_opaque_types_in_bounds<'tcx>( val.fold_with(&mut visitor) } -/// Determines whether an item is directly annotated with `doc(hidden)`. -fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - 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))) -} - /// Determines whether an item is annotated with `doc(notable_trait)`. pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.get_attrs(def_id, sym::doc) @@ -1702,7 +1695,6 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option RustdocVisitor<'a, 'tcx> { .unwrap_or(target_def_id); item_def_id != import_def_id && self.cx.cache.effective_visibilities.is_directly_public(tcx, item_def_id.to_def_id()) - && !tcx.is_doc_hidden(item_def_id) + && !tcx.is_doc_hidden(item_def_id.to_def_id()) && !inherits_doc_hidden(tcx, item_def_id, None) } diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs index a323c7cf8307c..94c0dd730e5eb 100644 --- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs +++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs @@ -149,7 +149,7 @@ struct BodyVisitor<'a, 'tcx> { fn is_public_macro(cx: &LateContext<'_>, def_id: LocalDefId) -> bool { (cx.effective_visibilities.is_exported(def_id) || find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. })) - && !cx.tcx.is_doc_hidden(def_id) + && !cx.tcx.is_doc_hidden(def_id.to_def_id()) } impl<'tcx> Visitor<'tcx> for BodyVisitor<'_, 'tcx> { diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index 6fc034b6fc5d2..85536f2952a6e 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -82,7 +82,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // can't be implemented for unsafe new && !sig.header.is_unsafe() // shouldn't be implemented when it is hidden in docs - && !cx.tcx.is_doc_hidden(impl_item.owner_id.def_id) + && !cx.tcx.is_doc_hidden(impl_item.owner_id.def_id.to_def_id()) // when the result of `new()` depends on a parameter we should not require // an impl of `Default` && impl_item.generics.params.is_empty()