diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 8dec8069bc7bd..fbec512b32f56 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -879,6 +879,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; providers.early_lint_checks = early_lint_checks; providers.env_var_os = env_var_os; + providers.is_unnamable = crate::queries::is_unnamable; limits::provide(providers); proc_macro_decls::provide(providers); rustc_const_eval::provide(providers); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 370e886c525fd..339d216eabdc5 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -5,7 +5,8 @@ use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::svh::Svh; use rustc_errors::timings::TimingSection; -use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::TyCtxt; @@ -107,3 +108,32 @@ impl Linker { codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames) } } + +/// Checks if the given `DefId` refers to an item that is unnamable, such as one defined in a const block. +/// +/// # Example +/// +/// ``` +/// pub fn f() { +/// // In here, `X` is not reachable outside of `f`, making it unnamable. +/// pub struct X; +/// } +/// ``` +pub(crate) fn is_unnamable(tcx: TyCtxt<'_>, did: DefId) -> bool { + let mut cur_did = did; + while let Some(parent) = tcx.opt_parent(cur_did) { + match tcx.def_kind(parent) { + // items defined in these can be linked to, as long as they are visible + DefKind::Mod | DefKind::ForeignMod => cur_did = parent, + // items in impls can be linked to, + // as long as we can link to the item the impl is on. + // since associated traits are not yet a thing, + // it should not be possible to refer to an impl item if + // the base type is not namable. + DefKind::Impl { .. } => return false, + // everything else does not have docs generated for it + _ => return true, + } + } + return false; +} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2941808e806f8..10093c5760727 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1547,6 +1547,22 @@ rustc_queries! { separate_provide_extern } + /// Checks if the given `DefId` refers to an item that is unnamable, such as one defined in a const block. + /// + /// Used by rustdoc. + /// + /// # Example + /// + /// ``` + /// pub fn f() { + /// // In here, `X` is not reachable outside of `f`, making it unnamable. + /// pub struct X; + /// } + /// ``` + query is_unnamable(def_id: DefId) -> bool { + desc { |tcx| "checking if `{}` is unnamable", tcx.def_path_str(def_id) } + } + query impl_parent(def_id: DefId) -> Option { desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } separate_provide_extern diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 493fdc6fb1b33..6da4b69ecf39f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -481,26 +481,6 @@ fn generate_item_def_id_path( Ok((url_parts, shortty, fqp)) } -/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block. -fn is_unnamable(tcx: TyCtxt<'_>, did: DefId) -> bool { - let mut cur_did = did; - while let Some(parent) = tcx.opt_parent(cur_did) { - match tcx.def_kind(parent) { - // items defined in these can be linked to, as long as they are visible - DefKind::Mod | DefKind::ForeignMod => cur_did = parent, - // items in impls can be linked to, - // as long as we can link to the item the impl is on. - // since associated traits are not a thing, - // it should not be possible to refer to an impl item if - // the base type is not namable. - DefKind::Impl { .. } => return false, - // everything else does not have docs generated for it - _ => return true, - } - } - return false; -} - fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] { if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] } } @@ -574,7 +554,7 @@ pub(crate) fn href_with_root_path( } _ => original_did, }; - if is_unnamable(cx.tcx(), did) { + if cx.tcx().is_unnamable(did) { return Err(HrefError::UnnamableItem); } let cache = cx.cache();