Skip to content

Commit 05ab16b

Browse files
Rollup merge of #103653 - GuillaumeGomez:missing-impl-private-json, r=notriddle
Add missing impl blocks for item reexported from private mod in JSON output Fixes #102583. Since we don't inline for the JSON output, the impl blocks from private modules are not present when we generate the output. To go around this limitation, in case the impl block doesn't have `#[doc(hidden)]` and is implementing a public item, we don't strip it. cc `@fmease` `@aDotInTheVoid` r? `@notriddle`
2 parents 2414a4c + 0ef36b8 commit 05ab16b

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

src/librustdoc/passes/stripper.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
//! A collection of utility functions for the `strip_*` passes.
22
use rustc_hir::def_id::DefId;
33
use rustc_middle::middle::privacy::EffectiveVisibilities;
4+
use rustc_span::symbol::sym;
5+
46
use std::mem;
57

6-
use crate::clean::{self, Item, ItemId, ItemIdSet};
8+
use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt};
79
use crate::fold::{strip_item, DocFolder};
810
use crate::formats::cache::Cache;
911

@@ -151,6 +153,22 @@ pub(crate) struct ImplStripper<'a> {
151153
pub(crate) document_private: bool,
152154
}
153155

156+
impl<'a> ImplStripper<'a> {
157+
#[inline]
158+
fn should_keep_impl(&self, item: &Item, for_def_id: DefId) -> bool {
159+
if !for_def_id.is_local() || self.retained.contains(&for_def_id.into()) {
160+
true
161+
} else if self.is_json_output {
162+
// If the "for" item is exported and the impl block isn't `#[doc(hidden)]`, then we
163+
// need to keep it.
164+
self.cache.effective_visibilities.is_exported(for_def_id)
165+
&& !item.attrs.lists(sym::doc).has_word(sym::hidden)
166+
} else {
167+
false
168+
}
169+
}
170+
}
171+
154172
impl<'a> DocFolder for ImplStripper<'a> {
155173
fn fold_item(&mut self, i: Item) -> Option<Item> {
156174
if let clean::ImplItem(ref imp) = *i.kind {
@@ -178,23 +196,25 @@ impl<'a> DocFolder for ImplStripper<'a> {
178196
return None;
179197
}
180198
}
199+
// Because we don't inline in `maybe_inline_local` if the output format is JSON,
200+
// we need to make a special check for JSON output: we want to keep it unless it has
201+
// a `#[doc(hidden)]` attribute if the `for_` type is exported.
181202
if let Some(did) = imp.for_.def_id(self.cache) {
182-
if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
183-
{
203+
if !imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did) {
184204
debug!("ImplStripper: impl item for stripped type; removing");
185205
return None;
186206
}
187207
}
188208
if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) {
189-
if did.is_local() && !self.retained.contains(&did.into()) {
209+
if !self.should_keep_impl(&i, did) {
190210
debug!("ImplStripper: impl item for stripped trait; removing");
191211
return None;
192212
}
193213
}
194214
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
195215
for typaram in generics {
196216
if let Some(did) = typaram.def_id(self.cache) {
197-
if did.is_local() && !self.retained.contains(&did.into()) {
217+
if !self.should_keep_impl(&i, did) {
198218
debug!(
199219
"ImplStripper: stripped item in trait's generics; removing impl"
200220
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/102583>.
2+
3+
// @set impl_S = "$.index[*][?(@.docs=='impl S')].id"
4+
// @has "$.index[*][?(@.name=='S')].inner.impls[*]" $impl_S
5+
// @set is_present = "$.index[*][?(@.name=='is_present')].id"
6+
// @is "$.index[*][?(@.docs=='impl S')].inner.items[*]" $is_present
7+
// @!has "$.index[*][?(@.name=='hidden_impl')]"
8+
// @!has "$.index[*][?(@.name=='hidden_fn')]"
9+
10+
#![no_std]
11+
12+
mod private_mod {
13+
pub struct S;
14+
15+
/// impl S
16+
impl S {
17+
pub fn is_present() {}
18+
#[doc(hidden)]
19+
pub fn hidden_fn() {}
20+
}
21+
22+
#[doc(hidden)]
23+
impl S {
24+
pub fn hidden_impl() {}
25+
}
26+
}
27+
28+
pub use private_mod::*;

0 commit comments

Comments
 (0)