Skip to content

Commit bc6d9b1

Browse files
Rollup merge of #156073 - GuillaumeGomez:doc-cfg-reexports, r=Urgau
[rustdoc] Fix `doc_cfg` feature on reexports Part of #150268. I don't mark the issue as fixed as I need to check the third case described in the issue. First commit comes from #156020, will need to rebase this PR once the original is merged. r? @Urgau
2 parents 54f67d2 + ba27564 commit bc6d9b1

3 files changed

Lines changed: 55 additions & 13 deletions

File tree

src/librustdoc/passes/propagate_doc_cfg.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,21 @@ impl CfgPropagator<'_, '_> {
7878
// We need to merge an item attributes with its parent's in case it's an impl as an
7979
// impl might not be defined in the same module as the item it implements.
8080
//
81+
// Same if it's an inlined item: we need to get the full original `cfg`.
82+
//
8183
// Otherwise, `cfg_info` already tracks everything we need so nothing else to do!
82-
if matches!(item.kind, ItemKind::ImplItem(_))
83-
&& let Some(mut next_def_id) = item.item_id.as_local_def_id()
84-
{
85-
while let Some(parent_def_id) = self.cx.tcx.opt_local_parent(next_def_id) {
86-
let x = load_attrs(self.cx.tcx, parent_def_id.to_def_id());
87-
add_only_cfg_attributes(&mut attrs, x);
88-
next_def_id = parent_def_id;
84+
if matches!(item.kind, ItemKind::ImplItem(_)) || item.inline_stmt_id.is_some() {
85+
if let Some(mut next_def_id) = item.item_id.as_local_def_id() {
86+
while let Some(parent_def_id) = self.cx.tcx.opt_local_parent(next_def_id) {
87+
let x = load_attrs(self.cx.tcx, parent_def_id.to_def_id());
88+
add_only_cfg_attributes(&mut attrs, x);
89+
next_def_id = parent_def_id;
90+
}
8991
}
9092
}
9193
// We also need to merge an item attributes with its parent's in case it's a macro with
9294
// the `#[macro_export]` attribute, because it might not be defined at crate root.
93-
if matches!(item.kind, ItemKind::MacroItem(_))
95+
else if matches!(item.kind, ItemKind::MacroItem(_))
9496
&& item.inner.attrs.other_attrs.iter().any(|attr| {
9597
matches!(
9698
attr,

src/librustdoc/visit_ast.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
244244
res: Res,
245245
renamed: Option<Symbol>,
246246
please_inline: bool,
247+
import_id: Option<LocalDefId>,
247248
) -> bool {
248249
debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}");
249250

@@ -338,20 +339,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
338339
let prev = mem::replace(&mut self.inlining, true);
339340
for &i in m.item_ids {
340341
let i = tcx.hir_item(i);
341-
self.visit_item_inner(i, None, Some(def_id));
342+
self.visit_item_inner(i, None, Some(import_id.unwrap_or(def_id)));
342343
}
343344
self.inlining = prev;
344345
true
345346
}
346347
Node::Item(it) if !is_glob => {
347348
let prev = mem::replace(&mut self.inlining, true);
348-
self.visit_item_inner(it, renamed, Some(def_id));
349+
self.visit_item_inner(it, renamed, Some(import_id.unwrap_or(def_id)));
349350
self.inlining = prev;
350351
true
351352
}
352353
Node::ForeignItem(it) if !is_glob => {
353354
let prev = mem::replace(&mut self.inlining, true);
354-
self.visit_foreign_item_inner(it, renamed, Some(def_id));
355+
self.visit_foreign_item_inner(it, renamed, Some(import_id.unwrap_or(def_id)));
355356
self.inlining = prev;
356357
true
357358
}
@@ -519,8 +520,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
519520
hir::UseKind::Glob => None,
520521
hir::UseKind::ListStem => unreachable!(),
521522
};
522-
if self.maybe_inline_local(item.owner_id.def_id, res, ident, please_inline)
523-
{
523+
if self.maybe_inline_local(
524+
item.owner_id.def_id,
525+
res,
526+
ident,
527+
please_inline,
528+
import_id,
529+
) {
524530
debug!("Inlining {:?}", item.owner_id.def_id);
525531
continue;
526532
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This test ensures that reexports cfgs are correctly computed.
2+
// Regression test for <https://github.com/rust-lang/rust/issues/150268>.
3+
4+
// ignore-tidy-linelength
5+
6+
#![feature(doc_cfg)]
7+
#![crate_name = "foo"]
8+
9+
//@has 'foo/struct.FlatBanana.html'
10+
//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature banana and non-crate feature yoyo only.'
11+
12+
//@has 'foo/struct.SubBanana.html'
13+
//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana and non-crate feature yoyo only.'
14+
15+
#[cfg(not(feature = "yoyo"))]
16+
pub use self::banana::*;
17+
18+
//@has 'foo/struct.Yolo.html'
19+
//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana only.'
20+
pub use self::banana::SubBanana as Yolo;
21+
22+
#[cfg(not(feature = "banana"))]
23+
mod banana {
24+
/// Depends on `banana` feature.
25+
pub struct FlatBanana {}
26+
27+
#[cfg(not(feature = "ananas"))]
28+
mod sub_banana {
29+
/// Also depends on `banana` feature.
30+
pub struct SubBanana {}
31+
}
32+
33+
pub use self::sub_banana::*;
34+
}

0 commit comments

Comments
 (0)