diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 1334595272f60..a329948433357 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -78,19 +78,21 @@ impl CfgPropagator<'_, '_> { // We need to merge an item attributes with its parent's in case it's an impl as an // impl might not be defined in the same module as the item it implements. // + // Same if it's an inlined item: we need to get the full original `cfg`. + // // Otherwise, `cfg_info` already tracks everything we need so nothing else to do! - if matches!(item.kind, ItemKind::ImplItem(_)) - && let Some(mut next_def_id) = item.item_id.as_local_def_id() - { - while let Some(parent_def_id) = self.cx.tcx.opt_local_parent(next_def_id) { - let x = load_attrs(self.cx.tcx, parent_def_id.to_def_id()); - add_only_cfg_attributes(&mut attrs, x); - next_def_id = parent_def_id; + if matches!(item.kind, ItemKind::ImplItem(_)) || item.inline_stmt_id.is_some() { + if let Some(mut next_def_id) = item.item_id.as_local_def_id() { + while let Some(parent_def_id) = self.cx.tcx.opt_local_parent(next_def_id) { + let x = load_attrs(self.cx.tcx, parent_def_id.to_def_id()); + add_only_cfg_attributes(&mut attrs, x); + next_def_id = parent_def_id; + } } } // We also need to merge an item attributes with its parent's in case it's a macro with // the `#[macro_export]` attribute, because it might not be defined at crate root. - if matches!(item.kind, ItemKind::MacroItem(_)) + else if matches!(item.kind, ItemKind::MacroItem(_)) && item.inner.attrs.other_attrs.iter().any(|attr| { matches!( attr, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 9e989bbd5fd9e..d0b02c20644fe 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -244,6 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { res: Res, renamed: Option, please_inline: bool, + import_id: Option, ) -> bool { debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}"); @@ -338,20 +339,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let prev = mem::replace(&mut self.inlining, true); for &i in m.item_ids { let i = tcx.hir_item(i); - self.visit_item_inner(i, None, Some(def_id)); + self.visit_item_inner(i, None, Some(import_id.unwrap_or(def_id))); } self.inlining = prev; true } Node::Item(it) if !is_glob => { let prev = mem::replace(&mut self.inlining, true); - self.visit_item_inner(it, renamed, Some(def_id)); + self.visit_item_inner(it, renamed, Some(import_id.unwrap_or(def_id))); self.inlining = prev; true } Node::ForeignItem(it) if !is_glob => { let prev = mem::replace(&mut self.inlining, true); - self.visit_foreign_item_inner(it, renamed, Some(def_id)); + self.visit_foreign_item_inner(it, renamed, Some(import_id.unwrap_or(def_id))); self.inlining = prev; true } @@ -519,8 +520,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::UseKind::Glob => None, hir::UseKind::ListStem => unreachable!(), }; - if self.maybe_inline_local(item.owner_id.def_id, res, ident, please_inline) - { + if self.maybe_inline_local( + item.owner_id.def_id, + res, + ident, + please_inline, + import_id, + ) { debug!("Inlining {:?}", item.owner_id.def_id); continue; } diff --git a/tests/rustdoc-html/doc-cfg/reexports.rs b/tests/rustdoc-html/doc-cfg/reexports.rs new file mode 100644 index 0000000000000..b954731b88222 --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/reexports.rs @@ -0,0 +1,34 @@ +// This test ensures that reexports cfgs are correctly computed. +// Regression test for . + +// ignore-tidy-linelength + +#![feature(doc_cfg)] +#![crate_name = "foo"] + +//@has 'foo/struct.FlatBanana.html' +//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature banana and non-crate feature yoyo only.' + +//@has 'foo/struct.SubBanana.html' +//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana and non-crate feature yoyo only.' + +#[cfg(not(feature = "yoyo"))] +pub use self::banana::*; + +//@has 'foo/struct.Yolo.html' +//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana only.' +pub use self::banana::SubBanana as Yolo; + +#[cfg(not(feature = "banana"))] +mod banana { + /// Depends on `banana` feature. + pub struct FlatBanana {} + + #[cfg(not(feature = "ananas"))] + mod sub_banana { + /// Also depends on `banana` feature. + pub struct SubBanana {} + } + + pub use self::sub_banana::*; +}