Skip to content

Commit

Permalink
Correctly handle reexports of #[doc(hidden)] is reexport does not u…
Browse files Browse the repository at this point in the history
…se `#[doc(inline)]`
  • Loading branch information
GuillaumeGomez committed Feb 14, 2023
1 parent 1ec1d94 commit 374f798
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
19 changes: 15 additions & 4 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2100,14 +2100,15 @@ fn get_all_import_attributes<'hir>(
tcx: TyCtxt<'hir>,
target_def_id: LocalDefId,
attributes: &mut Vec<ast::Attribute>,
is_inline: bool,
) {
let hir_map = tcx.hir();
let mut visitor = OneLevelVisitor::new(hir_map, target_def_id);
let mut visited = FxHashSet::default();
// If the item is an import and has at least a path with two parts, we go into it.
while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) {
// We add the attributes from this import into the list.
add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()));
add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);

let def_id = if path.segments.len() > 1 {
match path.segments[path.segments.len() - 2].res {
Expand Down Expand Up @@ -2189,7 +2190,16 @@ fn filter_tokens_from_list(
/// * `doc(inline)`
/// * `doc(no_inline)`
/// * `doc(hidden)`
fn add_without_unwanted_attributes(attrs: &mut Vec<ast::Attribute>, new_attrs: &[ast::Attribute]) {
fn add_without_unwanted_attributes(
attrs: &mut Vec<ast::Attribute>,
new_attrs: &[ast::Attribute],
is_inline: bool,
) {
// If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything.
if !is_inline {
attrs.extend_from_slice(new_attrs);
return;
}
for attr in new_attrs {
let mut attr = attr.clone();
match attr.kind {
Expand Down Expand Up @@ -2321,9 +2331,10 @@ fn clean_maybe_renamed_item<'tcx>(
{
// First, we add the attributes from the current import.
extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id()));
let is_inline = extra_attrs.lists(sym::doc).get_word_attr(sym::inline).is_some();
// Then we get all the various imports' attributes.
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs);
add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id));
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline);
add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline);
} else {
// We only keep the item's attributes.
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
Expand Down
13 changes: 10 additions & 3 deletions tests/rustdoc/reexport-attr-merge.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Regression test for <https://github.com/rust-lang/rust/issues/59368>.
// The goal is to ensure that `doc(hidden)`, `doc(inline)` and `doc(no_inline`)
// The goal is to ensure that `doc(hidden)`, `doc(inline)` and `doc(no_inline)`
// are not copied from an item when inlined.

#![crate_name = "foo"]
#![feature(doc_cfg)]
Expand All @@ -15,12 +16,18 @@ pub use Foo as Foo1;
#[doc(hidden, inline)]
pub use Foo1 as Foo2;

// First we ensure that none of the other items are generated.
// @count - '//a[@class="struct"]' 1
// First we ensure that only the reexport `Bar2` and the inlined struct `Bar`
// are inlined.
// @count - '//a[@class="struct"]' 2
// Then we check that both `cfg` are displayed.
// @has - '//*[@class="stab portability"]' 'foo'
// @has - '//*[@class="stab portability"]' 'bar'
// And finally we check that the only element displayed is `Bar`.
// @has - '//a[@class="struct"]' 'Bar'
#[doc(inline)]
pub use Foo2 as Bar;

// This one should appear but `Bar2` won't be linked because there is no
// `#[doc(inline)]`.
// @has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;'
pub use Foo2 as Bar2;

0 comments on commit 374f798

Please sign in to comment.