Skip to content

Commit 1236fa2

Browse files
Rollup merge of #119997 - GuillaumeGomez:fix-stripped-impl-on-ty-alias, r=notriddle
Fix impl stripped in rustdoc HTML whereas it should not be in case the impl is implemented on a type alias Fixes #119015. I talked about it a bit with ```@petrochenkov.``` They might change what `EffectiveVisibilities` return for impl items like this one and make them not only reachable but also re-exported, which would fix this case. It could also potentially break other things, so it'll be done whenever they can and then we can check together. Surprisingly, this fix is making rustdoc even closer to rustc in term of errors (the CI currently fails because currently accepted broken codes aren't working anymore with this change). Not sure exactly why though. This is linked to #110631 from what I could find. So either I'm missing something here, or we consider it's ok and we consider the failing tests as "should fail" and I'll update `rustdoc-ui` ones. r? ```@notriddle```
2 parents 159bdc1 + 0933f48 commit 1236fa2

File tree

3 files changed

+57
-19
lines changed

3 files changed

+57
-19
lines changed

src/librustdoc/passes/stripper.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,10 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
5656
| clean::TraitItem(..)
5757
| clean::FunctionItem(..)
5858
| clean::VariantItem(..)
59-
| clean::MethodItem(..)
6059
| clean::ForeignFunctionItem(..)
6160
| clean::ForeignStaticItem(..)
6261
| clean::ConstantItem(..)
6362
| clean::UnionItem(..)
64-
| clean::AssocConstItem(..)
65-
| clean::AssocTypeItem(..)
6663
| clean::TraitAliasItem(..)
6764
| clean::MacroItem(..)
6865
| clean::ForeignTypeItem => {
@@ -80,6 +77,16 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
8077
}
8178
}
8279

80+
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
81+
let item_id = i.item_id;
82+
if item_id.is_local()
83+
&& !self.effective_visibilities.is_reachable(self.tcx, item_id.expect_def_id())
84+
{
85+
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
86+
return None;
87+
}
88+
}
89+
8390
clean::StructFieldItem(..) => {
8491
if i.visibility(self.tcx) != Some(Visibility::Public) {
8592
return Some(strip_item(i));
@@ -192,16 +199,16 @@ impl<'a> DocFolder for ImplStripper<'a, '_> {
192199
&& imp.items.iter().all(|i| {
193200
let item_id = i.item_id;
194201
item_id.is_local()
195-
&& !is_item_reachable(
196-
self.tcx,
197-
self.is_json_output,
198-
&self.cache.effective_visibilities,
199-
item_id,
200-
)
202+
&& !self
203+
.cache
204+
.effective_visibilities
205+
.is_reachable(self.tcx, item_id.expect_def_id())
201206
})
202207
{
208+
debug!("ImplStripper: no public item; removing {imp:?}");
203209
return None;
204210
} else if imp.items.is_empty() && i.doc_value().is_empty() {
211+
debug!("ImplStripper: no item and no doc; removing {imp:?}");
205212
return None;
206213
}
207214
}
@@ -212,21 +219,21 @@ impl<'a> DocFolder for ImplStripper<'a, '_> {
212219
&& !imp.for_.is_assoc_ty()
213220
&& !self.should_keep_impl(&i, did)
214221
{
215-
debug!("ImplStripper: impl item for stripped type; removing");
222+
debug!("ImplStripper: impl item for stripped type; removing {imp:?}");
216223
return None;
217224
}
218225
if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id())
219226
&& !self.should_keep_impl(&i, did)
220227
{
221-
debug!("ImplStripper: impl item for stripped trait; removing");
228+
debug!("ImplStripper: impl item for stripped trait; removing {imp:?}");
222229
return None;
223230
}
224231
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
225232
for typaram in generics {
226233
if let Some(did) = typaram.def_id(self.cache)
227234
&& !self.should_keep_impl(&i, did)
228235
{
229-
debug!("ImplStripper: stripped item in trait's generics; removing impl");
236+
debug!("ImplStripper: stripped item in trait's generics; removing {imp:?}");
230237
return None;
231238
}
232239
}

tests/rustdoc/async-fn.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ impl Foo {
4848

4949
pub trait Pattern<'a> {}
5050

51+
impl Pattern<'_> for () {}
52+
5153
pub trait Trait<const N: usize> {}
5254
// @has async_fn/fn.const_generics.html
5355
// @has - '//pre[@class="rust item-decl"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)'
@@ -57,18 +59,18 @@ pub async fn const_generics<const N: usize>(_: impl Trait<N>) {}
5759
// regression test for #63037
5860
// @has async_fn/fn.elided.html
5961
// @has - '//pre[@class="rust item-decl"]' 'pub async fn elided(foo: &str) -> &str'
60-
pub async fn elided(foo: &str) -> &str {}
62+
pub async fn elided(foo: &str) -> &str { "" }
6163
// This should really be shown as written, but for implementation reasons it's difficult.
6264
// See `impl Clean for TyKind::Ref`.
6365
// @has async_fn/fn.user_elided.html
6466
// @has - '//pre[@class="rust item-decl"]' 'pub async fn user_elided(foo: &str) -> &str'
65-
pub async fn user_elided(foo: &'_ str) -> &str {}
67+
pub async fn user_elided(foo: &'_ str) -> &str { "" }
6668
// @has async_fn/fn.static_trait.html
6769
// @has - '//pre[@class="rust item-decl"]' 'pub async fn static_trait(foo: &str) -> Box<dyn Bar>'
68-
pub async fn static_trait(foo: &str) -> Box<dyn Bar> {}
70+
pub async fn static_trait(foo: &str) -> Box<dyn Bar> { Box::new(()) }
6971
// @has async_fn/fn.lifetime_for_trait.html
7072
// @has - '//pre[@class="rust item-decl"]' "pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_>"
71-
pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> {}
73+
pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> { Box::new(()) }
7274
// @has async_fn/fn.elided_in_input_trait.html
7375
// @has - '//pre[@class="rust item-decl"]' "pub async fn elided_in_input_trait(t: impl Pattern<'_>)"
7476
pub async fn elided_in_input_trait(t: impl Pattern<'_>) {}
@@ -78,18 +80,20 @@ struct AsyncFdReadyGuard<'a, T> { x: &'a T }
7880
impl Foo {
7981
// @has async_fn/struct.Foo.html
8082
// @has - '//*[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar ) -> impl Iterator<Item = &usize>'
81-
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
83+
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {
84+
[0].iter()
85+
}
8286
// taken from `tokio` as an example of a method that was particularly bad before
8387
// @has - '//*[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
84-
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
88+
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> { Err(()) }
8589
// @has - '//*[@class="method"]' "pub async fn mut_self(&mut self)"
8690
pub async fn mut_self(&mut self) {}
8791
}
8892

8993
// test named lifetimes, just in case
9094
// @has async_fn/fn.named.html
9195
// @has - '//pre[@class="rust item-decl"]' "pub async fn named<'a, 'b>(foo: &'a str) -> &'b str"
92-
pub async fn named<'a, 'b>(foo: &'a str) -> &'b str {}
96+
pub async fn named<'a, 'b>(foo: &'a str) -> &'b str { "" }
9397
// @has async_fn/fn.named_trait.html
9498
// @has - '//pre[@class="rust item-decl"]' "pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b>"
9599
pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b> {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![crate_name = "foo"]
2+
3+
// @has 'foo/index.html'
4+
// There should be only `type A`.
5+
// @count - '//*[@class="item-table"]//*[@class="item-name"]' 1
6+
// @has - '//*[@class="item-name"]/a[@href="type.A.html"]' 'A'
7+
8+
mod foo {
9+
pub struct S;
10+
}
11+
12+
use foo::S;
13+
14+
pub type A = S;
15+
16+
// @has 'foo/type.A.html'
17+
// @has - '//*[@id="method.default"]/h4' 'fn default() -> Self'
18+
impl Default for A {
19+
fn default() -> Self {
20+
S
21+
}
22+
}
23+
24+
// @has - '//*[@id="method.a"]/h4' 'pub fn a(&self)'
25+
impl A {
26+
pub fn a(&self) {}
27+
}

0 commit comments

Comments
 (0)