diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d1601272af759..04559bd67bf6d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::Mutability; use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty::{self, TyCtxt}; +use rustc_span::def_id::LOCAL_CRATE; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; @@ -378,20 +379,32 @@ pub(crate) fn build_impl( let tcx = cx.tcx; let associated_trait = tcx.impl_trait_ref(did); + // Do not inline compiler-internal items unless we're a compiler-internal crate. + let is_compiler_internal = |did| { + if let Some(stab) = tcx.lookup_stability(did) { + stab.is_unstable() && stab.feature == sym::rustc_private + } else { + false + } + }; + let document_compiler_internal = is_compiler_internal(LOCAL_CRATE.as_def_id()); + let is_directly_public = |cx: &mut DocContext<'_>, did| { + if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { + return false; + } + if !document_compiler_internal && is_compiler_internal(did) { + return false; + } + true + }; + // Only inline impl if the implemented trait is // reachable in rustdoc generated documentation if !did.is_local() { if let Some(traitref) = associated_trait { - let did = traitref.def_id; - if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { + if !is_directly_public(cx, traitref.def_id) { return; } - - if let Some(stab) = tcx.lookup_stability(did) { - if stab.is_unstable() && stab.feature == sym::rustc_private { - return; - } - } } } @@ -412,15 +425,9 @@ pub(crate) fn build_impl( // reachable in rustdoc generated documentation if !did.is_local() { if let Some(did) = for_.def_id(&cx.cache) { - if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { + if !is_directly_public(cx, did) { return; } - - if let Some(stab) = tcx.lookup_stability(did) { - if stab.is_unstable() && stab.feature == sym::rustc_private { - return; - } - } } } diff --git a/src/test/rustdoc/auxiliary/issue-106421-force-unstable.rs b/src/test/rustdoc/auxiliary/issue-106421-force-unstable.rs new file mode 100644 index 0000000000000..d8b9abfa2c2a7 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-106421-force-unstable.rs @@ -0,0 +1,9 @@ +// compile-flags: -Zforce-unstable-if-unmarked +#![crate_name="foo"] +pub struct FatalError; + +impl FatalError { + pub fn raise(self) -> ! { + loop {} + } +} diff --git a/src/test/rustdoc/issue-106421-not-internal.rs b/src/test/rustdoc/issue-106421-not-internal.rs new file mode 100644 index 0000000000000..1477b7b5d2a06 --- /dev/null +++ b/src/test/rustdoc/issue-106421-not-internal.rs @@ -0,0 +1,8 @@ +// aux-build:issue-106421-force-unstable.rs +// ignore-cross-compile +// This is the version where a non-compiler-internal crate inlines a compiler-internal one. +// In this case, the item shouldn't be documented, because regular users can't get at it. +extern crate foo; + +// @!has issue_106421_not_internal/struct.FatalError.html '//*[@id="method.raise"]' 'fn raise' +pub use foo::FatalError; diff --git a/src/test/rustdoc/issue-106421.rs b/src/test/rustdoc/issue-106421.rs new file mode 100644 index 0000000000000..7059f57ff5031 --- /dev/null +++ b/src/test/rustdoc/issue-106421.rs @@ -0,0 +1,8 @@ +// aux-build:issue-106421-force-unstable.rs +// ignore-cross-compile +// compile-flags: -Zforce-unstable-if-unmarked + +extern crate foo; + +// @has issue_106421/struct.FatalError.html '//*[@id="method.raise"]' 'fn raise' +pub use foo::FatalError;