Skip to content

Commit 6908c73

Browse files
committed
Auto merge of rust-lang#114012 - GuillaumeGomez:fix-113982, r=notriddle
Fix missing attribute merge on glob foreign re-exports Fixes rust-lang#113982. The attributes were not merged with the import's in case of glob re-export of foreign items. r? `@notriddle`
2 parents 601a34d + 7150e35 commit 6908c73

File tree

5 files changed

+61
-18
lines changed

5 files changed

+61
-18
lines changed

src/librustdoc/clean/inline.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ pub(crate) fn try_inline_glob(
141141
current_mod: LocalDefId,
142142
visited: &mut DefIdSet,
143143
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
144+
import: &hir::Item<'_>,
144145
) -> Option<Vec<clean::Item>> {
145146
let did = res.opt_def_id()?;
146147
if did.is_local() {
@@ -158,7 +159,15 @@ pub(crate) fn try_inline_glob(
158159
.filter(|child| !child.reexport_chain.is_empty())
159160
.filter_map(|child| child.res.opt_def_id())
160161
.collect();
161-
let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports));
162+
let attrs = cx.tcx.hir().attrs(import.hir_id());
163+
let mut items = build_module_items(
164+
cx,
165+
did,
166+
visited,
167+
inlined_names,
168+
Some(&reexports),
169+
Some((attrs, Some(import.owner_id.def_id.to_def_id()))),
170+
);
162171
items.retain(|item| {
163172
if let Some(name) = item.name {
164173
// If an item with the same type and name already exists,
@@ -549,7 +558,7 @@ pub(crate) fn build_impl(
549558
}
550559

551560
fn build_module(cx: &mut DocContext<'_>, did: DefId, visited: &mut DefIdSet) -> clean::Module {
552-
let items = build_module_items(cx, did, visited, &mut FxHashSet::default(), None);
561+
let items = build_module_items(cx, did, visited, &mut FxHashSet::default(), None, None);
553562

554563
let span = clean::Span::new(cx.tcx.def_span(did));
555564
clean::Module { items, span }
@@ -561,6 +570,7 @@ fn build_module_items(
561570
visited: &mut DefIdSet,
562571
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
563572
allowed_def_ids: Option<&DefIdSet>,
573+
attrs: Option<(&[ast::Attribute], Option<DefId>)>,
564574
) -> Vec<clean::Item> {
565575
let mut items = Vec::new();
566576

@@ -615,7 +625,7 @@ fn build_module_items(
615625
cfg: None,
616626
inline_stmt_id: None,
617627
});
618-
} else if let Some(i) = try_inline(cx, res, item.ident.name, None, visited) {
628+
} else if let Some(i) = try_inline(cx, res, item.ident.name, attrs, visited) {
619629
items.extend(i)
620630
}
621631
}

src/librustdoc/clean/mod.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -132,25 +132,31 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
132132
});
133133

134134
let kind = ModuleItem(Module { items, span });
135-
generate_item_with_correct_attrs(cx, kind, doc.def_id, doc.name, doc.import_id, doc.renamed)
135+
generate_item_with_correct_attrs(
136+
cx,
137+
kind,
138+
doc.def_id.to_def_id(),
139+
doc.name,
140+
doc.import_id,
141+
doc.renamed,
142+
)
136143
}
137144

138145
fn generate_item_with_correct_attrs(
139146
cx: &mut DocContext<'_>,
140147
kind: ItemKind,
141-
local_def_id: LocalDefId,
148+
def_id: DefId,
142149
name: Symbol,
143150
import_id: Option<LocalDefId>,
144151
renamed: Option<Symbol>,
145152
) -> Item {
146-
let def_id = local_def_id.to_def_id();
147153
let target_attrs = inline::load_attrs(cx, def_id);
148154
let attrs = if let Some(import_id) = import_id {
149155
let is_inline = inline::load_attrs(cx, import_id.to_def_id())
150156
.lists(sym::doc)
151157
.get_word_attr(sym::inline)
152158
.is_some();
153-
let mut attrs = get_all_import_attributes(cx, import_id, local_def_id, is_inline);
159+
let mut attrs = get_all_import_attributes(cx, import_id, def_id, is_inline);
154160
add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None);
155161
attrs
156162
} else {
@@ -2308,10 +2314,10 @@ fn clean_bare_fn_ty<'tcx>(
23082314
pub(crate) fn reexport_chain<'tcx>(
23092315
tcx: TyCtxt<'tcx>,
23102316
import_def_id: LocalDefId,
2311-
target_def_id: LocalDefId,
2317+
target_def_id: DefId,
23122318
) -> &'tcx [Reexport] {
23132319
for child in tcx.module_children_local(tcx.local_parent(import_def_id)) {
2314-
if child.res.opt_def_id() == Some(target_def_id.to_def_id())
2320+
if child.res.opt_def_id() == Some(target_def_id)
23152321
&& child.reexport_chain.first().and_then(|r| r.id()) == Some(import_def_id.to_def_id())
23162322
{
23172323
return &child.reexport_chain;
@@ -2324,7 +2330,7 @@ pub(crate) fn reexport_chain<'tcx>(
23242330
fn get_all_import_attributes<'hir>(
23252331
cx: &mut DocContext<'hir>,
23262332
import_def_id: LocalDefId,
2327-
target_def_id: LocalDefId,
2333+
target_def_id: DefId,
23282334
is_inline: bool,
23292335
) -> Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)> {
23302336
let mut attrs = Vec::new();
@@ -2541,7 +2547,7 @@ fn clean_maybe_renamed_item<'tcx>(
25412547
vec![generate_item_with_correct_attrs(
25422548
cx,
25432549
kind,
2544-
item.owner_id.def_id,
2550+
item.owner_id.def_id.to_def_id(),
25452551
name,
25462552
import_id,
25472553
renamed,
@@ -2691,6 +2697,7 @@ fn clean_use_statement_inner<'tcx>(
26912697
let inline_attr = attrs.lists(sym::doc).get_word_attr(sym::inline);
26922698
let pub_underscore = visibility.is_public() && name == kw::Underscore;
26932699
let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id);
2700+
let import_def_id = import.owner_id.def_id.to_def_id();
26942701

26952702
// The parent of the module in which this import resides. This
26962703
// is the same as `current_mod` if that's already the top
@@ -2741,9 +2748,14 @@ fn clean_use_statement_inner<'tcx>(
27412748
let inner = if kind == hir::UseKind::Glob {
27422749
if !denied {
27432750
let mut visited = DefIdSet::default();
2744-
if let Some(items) =
2745-
inline::try_inline_glob(cx, path.res, current_mod, &mut visited, inlined_names)
2746-
{
2751+
if let Some(items) = inline::try_inline_glob(
2752+
cx,
2753+
path.res,
2754+
current_mod,
2755+
&mut visited,
2756+
inlined_names,
2757+
import,
2758+
) {
27472759
return items;
27482760
}
27492761
}
@@ -2759,7 +2771,6 @@ fn clean_use_statement_inner<'tcx>(
27592771
denied = true;
27602772
}
27612773
if !denied {
2762-
let import_def_id = import.owner_id.to_def_id();
27632774
if let Some(mut items) = inline::try_inline(
27642775
cx,
27652776
path.res,
@@ -2779,7 +2790,7 @@ fn clean_use_statement_inner<'tcx>(
27792790
Import::new_simple(name, resolve_use_source(cx, path), true)
27802791
};
27812792

2782-
vec![Item::from_def_id_and_parts(import.owner_id.to_def_id(), None, ImportItem(inner), cx)]
2793+
vec![Item::from_def_id_and_parts(import_def_id, None, ImportItem(inner), cx)]
27832794
}
27842795

27852796
fn clean_maybe_renamed_foreign_item<'tcx>(

src/librustdoc/visit_ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
282282
// made reachable by cross-crate inlining which we're checking here.
283283
// (this is done here because we need to know this upfront).
284284
crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did);
285-
if is_hidden {
285+
if is_hidden || glob {
286286
return false;
287287
}
288288
// We store inlined foreign items otherwise, it'd mean that the `use` item would be kept
@@ -376,7 +376,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
376376
return true;
377377
}
378378
let tcx = self.cx.tcx;
379-
let item_def_id = reexport_chain(tcx, import_def_id, target_def_id)
379+
let item_def_id = reexport_chain(tcx, import_def_id, target_def_id.to_def_id())
380380
.iter()
381381
.flat_map(|reexport| reexport.id())
382382
.map(|id| id.expect_local())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#![crate_name = "colors"]
2+
3+
pub struct Color;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// aux-build: issue-113982-doc_auto_cfg-reexport-foreign.rs
2+
3+
#![feature(no_core, doc_auto_cfg)]
4+
#![no_core]
5+
#![crate_name = "foo"]
6+
7+
extern crate colors;
8+
9+
// @has 'foo/index.html' '//*[@class="stab portability"]' 'Non-colors'
10+
// @has 'foo/struct.Color.html' '//*[@class="stab portability"]' \
11+
// 'Available on non-crate feature colors only.'
12+
#[cfg(not(feature = "colors"))]
13+
pub use colors::*;
14+
15+
// @has 'foo/index.html' '//*[@class="stab portability"]' 'Non-fruits'
16+
// @has 'foo/struct.Red.html' '//*[@class="stab portability"]' \
17+
// 'Available on non-crate feature fruits only.'
18+
#[cfg(not(feature = "fruits"))]
19+
pub use colors::Color as Red;

0 commit comments

Comments
 (0)