Rollup merge of #141831 - lolbinarycat:rustdoc-extern-reexport-135092, r=GuillaumeGomez

rustdoc: fix attrs of locally reexported foreign items

fixes rust-lang/rust#135092

also tweaks a few outdated/misleading comments.

r? `@GuillaumeGomez`
This commit is contained in:
Guillaume Gomez 2025-07-03 19:45:30 +02:00 committed by GitHub
commit 678ec9bbd4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 52 additions and 13 deletions

View file

@ -66,8 +66,8 @@ use crate::visit_ast::Module as DocModule;
pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
let mut items: Vec<Item> = vec![];
let mut inserted = FxHashSet::default();
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
items.extend(doc.foreigns.iter().map(|(item, renamed, import_id)| {
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed, *import_id);
if let Some(name) = item.name
&& (cx.render_options.document_hidden || !item.is_doc_hidden())
{
@ -89,7 +89,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
Some(item)
}));
// Split up imports from all other items.
// Split up glob imports from all other items.
//
// This covers the case where somebody does an import which should pull in an item,
// but there's already an item with the same namespace and same name. Rust gives
@ -2762,7 +2762,6 @@ fn clean_maybe_renamed_item<'tcx>(
import_id: Option<LocalDefId>,
) -> Vec<Item> {
use hir::ItemKind;
fn get_name(
cx: &DocContext<'_>,
item: &hir::Item<'_>,
@ -2974,6 +2973,7 @@ fn clean_extern_crate<'tcx>(
&& !cx.is_json_output();
let krate_owner_def_id = krate.owner_id.def_id;
if please_inline
&& let Some(items) = inline::try_inline(
cx,
@ -3135,6 +3135,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
cx: &mut DocContext<'tcx>,
item: &hir::ForeignItem<'tcx>,
renamed: Option<Symbol>,
import_id: Option<LocalDefId>,
) -> Item {
let def_id = item.owner_id.to_def_id();
cx.with_param_env(def_id, |cx| {
@ -3150,11 +3151,13 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
hir::ForeignItemKind::Type => ForeignTypeItem,
};
Item::from_def_id_and_parts(
item.owner_id.def_id.to_def_id(),
Some(renamed.unwrap_or(item.ident.name)),
kind,
generate_item_with_correct_attrs(
cx,
kind,
item.owner_id.def_id.to_def_id(),
item.ident.name,
import_id,
renamed,
)
})
}

View file

@ -38,9 +38,18 @@ pub(crate) struct Module<'hir> {
(LocalDefId, Option<Symbol>),
(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>),
>,
/// Same as for `items`.
/// (def_id, renamed) -> (res, local_import_id)
///
/// `inlined_foreigns` only contains `extern` items
/// that are cross-crate inlined.
///
/// Locally inlined `extern` items are
/// stored in `foreigns` with the `import_id` set,
/// analogous to how `items` is.
pub(crate) inlined_foreigns: FxIndexMap<(DefId, Option<Symbol>), (Res, LocalDefId)>,
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
/// (item, renamed, import_id)
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>, Option<LocalDefId>)>,
}
impl Module<'_> {
@ -327,7 +336,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
Node::ForeignItem(it) if !glob => {
let prev = mem::replace(&mut self.inlining, true);
self.visit_foreign_item_inner(it, renamed);
self.visit_foreign_item_inner(it, renamed, Some(def_id));
self.inlining = prev;
true
}
@ -432,7 +441,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::ItemKind::ForeignMod { items, .. } => {
for item in items {
let item = tcx.hir_foreign_item(item.id);
self.visit_foreign_item_inner(item, None);
self.visit_foreign_item_inner(item, None, None);
}
}
// If we're inlining, skip private items.
@ -527,10 +536,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
&mut self,
item: &'tcx hir::ForeignItem<'_>,
renamed: Option<Symbol>,
import_id: Option<LocalDefId>,
) {
// If inlining we only want to include public functions.
if !self.inlining || self.cx.tcx.visibility(item.owner_id).is_public() {
self.modules.last_mut().unwrap().foreigns.push((item, renamed));
self.modules.last_mut().unwrap().foreigns.push((item, renamed, import_id));
}
}

View file

@ -0,0 +1,26 @@
// Test to make sure reexports of extern items are combined
// <https://github.com/rust-lang/rust/issues/135092>
#![crate_name = "foo"]
mod native {
extern "C" {
/// bar.
pub fn bar();
}
/// baz.
pub fn baz() {}
}
//@ has 'foo/fn.bar.html'
//@ has - '//div[@class="docblock"]' 'bar.'
//@ has - '//div[@class="docblock"]' 'foo'
/// foo
pub use native::bar;
//@ has 'foo/fn.baz.html'
//@ has - '//div[@class="docblock"]' 'baz.'
//@ has - '//div[@class="docblock"]' 'foo'
/// foo
pub use native::baz;