Skip to content

Commit 9eb3a7c

Browse files
committed
Auto merge of #79349 - Nemo157:issue-79201, r=jyn514
Apply `doc(cfg)` from parent items while collecting trait impls Because trait impls bypass the standard `clean` hierarchy they do not participate in the `propagate_doc_cfg` pass, so instead we need to pre-collect all possible `doc(cfg)` attributes that will apply to them when cleaning. fixes #79201
2 parents 2225ee1 + d93f1d6 commit 9eb3a7c

File tree

5 files changed

+76
-8
lines changed

5 files changed

+76
-8
lines changed

src/librustdoc/clean/inline.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,6 @@ crate fn build_impl(
339339
return;
340340
}
341341

342-
let attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
343-
debug!("merged_attrs={:?}", attrs);
344-
345342
let tcx = cx.tcx;
346343
let associated_trait = tcx.impl_trait_ref(did);
347344

@@ -435,7 +432,7 @@ crate fn build_impl(
435432

436433
debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
437434

438-
ret.push(clean::Item::from_def_id_and_parts(
435+
let mut item = clean::Item::from_def_id_and_parts(
439436
did,
440437
None,
441438
clean::ImplItem(clean::Impl {
@@ -450,7 +447,10 @@ crate fn build_impl(
450447
blanket_impl: None,
451448
}),
452449
cx,
453-
));
450+
);
451+
item.attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
452+
debug!("merged_attrs={:?}", item.attrs);
453+
ret.push(item);
454454
}
455455

456456
fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) -> clean::Module {

src/librustdoc/passes/collect_trait_impls.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::fold::DocFolder;
55

66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
8+
use rustc_middle::ty::DefIdTree;
89
use rustc_span::symbol::sym;
910

1011
crate const COLLECT_TRAIT_IMPLS: Pass = Pass {
@@ -90,7 +91,32 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
9091
for &impl_node in cx.tcx.hir().trait_impls(trait_did) {
9192
let impl_did = cx.tcx.hir().local_def_id(impl_node);
9293
cx.tcx.sess.time("build_local_trait_impl", || {
93-
inline::build_impl(cx, None, impl_did.to_def_id(), None, &mut new_items);
94+
let mut extra_attrs = Vec::new();
95+
let mut parent = cx.tcx.parent(impl_did.to_def_id());
96+
while let Some(did) = parent {
97+
extra_attrs.extend(
98+
cx.tcx
99+
.get_attrs(did)
100+
.iter()
101+
.filter(|attr| attr.has_name(sym::doc))
102+
.filter(|attr| {
103+
if let Some([attr]) = attr.meta_item_list().as_deref() {
104+
attr.has_name(sym::cfg)
105+
} else {
106+
false
107+
}
108+
})
109+
.cloned(),
110+
);
111+
parent = cx.tcx.parent(did);
112+
}
113+
inline::build_impl(
114+
cx,
115+
None,
116+
impl_did.to_def_id(),
117+
Some(&extra_attrs),
118+
&mut new_items,
119+
);
94120
});
95121
}
96122
}

src/test/rustdoc/doc-cfg.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ pub mod unix_only {
2525
// @has doc_cfg/unix_only/trait.ArmOnly.html \
2626
// '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \
2727
// 'This is supported on Unix and ARM only.'
28-
// @count - '//*[@class="stab portability"]' 2
28+
// @count - '//*[@class="stab portability"]' 1
2929
#[doc(cfg(target_arch = "arm"))]
3030
pub trait ArmOnly {
3131
fn unix_and_arm_only_function();
3232
}
3333

34+
#[doc(cfg(target_arch = "arm"))]
3435
impl ArmOnly for super::Portable {
3536
fn unix_and_arm_only_function() {}
3637
}

src/test/rustdoc/issue-79201.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#![feature(doc_cfg)]
2+
3+
// @has 'issue_79201/trait.Foo.html'
4+
// @count - '//*[@class="stab portability"]' 6
5+
// @matches - '//*[@class="stab portability"]' 'crate feature foo-root'
6+
// @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod'
7+
// @matches - '//*[@class="stab portability"]' 'crate feature foo-private-mod'
8+
// @matches - '//*[@class="stab portability"]' 'crate feature foo-fn'
9+
// @matches - '//*[@class="stab portability"]' 'crate feature foo-method'
10+
11+
pub trait Foo {}
12+
13+
#[doc(cfg(feature = "foo-root"))]
14+
impl crate::Foo for usize {}
15+
16+
#[doc(cfg(feature = "foo-public-mod"))]
17+
pub mod public {
18+
impl crate::Foo for u8 {}
19+
}
20+
21+
#[doc(cfg(feature = "foo-private-mod"))]
22+
mod private {
23+
impl crate::Foo for u16 {}
24+
}
25+
26+
#[doc(cfg(feature = "foo-const"))]
27+
const _: () = {
28+
impl crate::Foo for u32 {}
29+
};
30+
31+
#[doc(cfg(feature = "foo-fn"))]
32+
fn __() {
33+
impl crate::Foo for u64 {}
34+
}
35+
36+
#[doc(cfg(feature = "foo-method"))]
37+
impl dyn Foo {
38+
fn __() {
39+
impl crate::Foo for u128 {}
40+
}
41+
}

src/tools/compiletest/src/runtest.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2442,7 +2442,7 @@ impl<'test> TestCx<'test> {
24422442
})
24432443
};
24442444
let mut diff = Command::new("diff");
2445-
diff.args(&["-u", "-r"]).args(&[out_dir, &compare_dir]);
2445+
diff.args(&["-u", "-r"]).args(&[&compare_dir, out_dir]);
24462446

24472447
let output = if let Some(pager) = pager {
24482448
let diff_pid = diff.stdout(Stdio::piped()).spawn().expect("failed to run `diff`");

0 commit comments

Comments
 (0)