Fix invalid display of inlined re-export
This commit is contained in:
parent
6b9236ed5a
commit
6fb4ce9f88
@ -90,6 +90,19 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
||||
}
|
||||
v
|
||||
}));
|
||||
items.extend(doc.inlined_foreigns.values().flat_map(|(res, renamed, local_import_id)| {
|
||||
let Some(def_id) = res.opt_def_id() else { return Vec::new() };
|
||||
let name = renamed.unwrap_or_else(|| cx.tcx.item_name(def_id));
|
||||
let import = cx.tcx.hir().expect_item(*local_import_id);
|
||||
match import.kind {
|
||||
hir::ItemKind::Use(path, kind) => {
|
||||
let hir::UsePath { segments, span, .. } = *path;
|
||||
let path = hir::Path { segments, res: *res, span };
|
||||
clean_use_statement_inner(import, name, &path, kind, cx, &mut Default::default())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}));
|
||||
items.extend(doc.items.values().flat_map(|(item, renamed, _)| {
|
||||
// Now we actually lower the imports, skipping everything else.
|
||||
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
|
||||
@ -2652,9 +2665,6 @@ fn clean_use_statement<'tcx>(
|
||||
let mut items = Vec::new();
|
||||
let hir::UsePath { segments, ref res, span } = *path;
|
||||
for &res in res {
|
||||
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
|
||||
continue;
|
||||
}
|
||||
let path = hir::Path { segments, res, span };
|
||||
items.append(&mut clean_use_statement_inner(import, name, &path, kind, cx, inlined_names));
|
||||
}
|
||||
@ -2669,6 +2679,9 @@ fn clean_use_statement_inner<'tcx>(
|
||||
cx: &mut DocContext<'tcx>,
|
||||
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
|
||||
) -> Vec<Item> {
|
||||
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res {
|
||||
return Vec::new();
|
||||
}
|
||||
// We need this comparison because some imports (for std types for example)
|
||||
// are "inserted" as well but directly by the compiler and they should not be
|
||||
// taken into account.
|
||||
|
@ -35,6 +35,9 @@ pub(crate) struct Module<'hir> {
|
||||
(LocalDefId, Option<Symbol>),
|
||||
(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>),
|
||||
>,
|
||||
/// Same as for `items`.
|
||||
pub(crate) inlined_foreigns:
|
||||
FxIndexMap<(DefId, Option<Symbol>), (Res, Option<Symbol>, LocalDefId)>,
|
||||
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
|
||||
}
|
||||
|
||||
@ -54,6 +57,7 @@ pub(crate) fn new(
|
||||
import_id,
|
||||
mods: Vec::new(),
|
||||
items: FxIndexMap::default(),
|
||||
inlined_foreigns: FxIndexMap::default(),
|
||||
foreigns: Vec::new(),
|
||||
}
|
||||
}
|
||||
@ -272,21 +276,30 @@ fn maybe_inline_local(
|
||||
return false;
|
||||
}
|
||||
|
||||
// For cross-crate impl inlining we need to know whether items are
|
||||
// reachable in documentation -- a previously unreachable item can be
|
||||
// made reachable by cross-crate inlining which we're checking here.
|
||||
// (this is done here because we need to know this upfront).
|
||||
if !ori_res_did.is_local() && !is_no_inline {
|
||||
crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did);
|
||||
return false;
|
||||
}
|
||||
|
||||
let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did);
|
||||
let Some(res_did) = ori_res_did.as_local() else {
|
||||
return false;
|
||||
// For cross-crate impl inlining we need to know whether items are
|
||||
// reachable in documentation -- a previously unreachable item can be
|
||||
// made reachable by cross-crate inlining which we're checking here.
|
||||
// (this is done here because we need to know this upfront).
|
||||
crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did);
|
||||
if is_hidden {
|
||||
return false;
|
||||
}
|
||||
// We store inlined foreign items otherwise, it'd mean that the `use` item would be kept
|
||||
// around. It's not a problem unless this `use` imports both a local AND a foreign item.
|
||||
// If a local item is inlined, its `use` is not supposed to still be around in `clean`,
|
||||
// which would make appear the `use` in the generated documentation like the local item
|
||||
// was not inlined even though it actually was.
|
||||
self.modules
|
||||
.last_mut()
|
||||
.unwrap()
|
||||
.inlined_foreigns
|
||||
.insert((ori_res_did, renamed), (res, renamed, def_id));
|
||||
return true;
|
||||
};
|
||||
|
||||
let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
|
||||
let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did);
|
||||
let item = tcx.hir().get_by_def_id(res_did);
|
||||
|
||||
if !please_inline {
|
||||
@ -314,7 +327,7 @@ fn maybe_inline_local(
|
||||
return false;
|
||||
}
|
||||
|
||||
let inlined = match tcx.hir().get_by_def_id(res_did) {
|
||||
let inlined = match item {
|
||||
// Bang macros are handled a bit on their because of how they are handled by the
|
||||
// compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
|
||||
// `#[doc(inline)]`, then we don't inline it.
|
||||
@ -346,7 +359,7 @@ fn maybe_inline_local(
|
||||
};
|
||||
self.view_item_stack.remove(&res_did);
|
||||
if inlined {
|
||||
self.cx.cache.inlined_items.insert(res_did.to_def_id());
|
||||
self.cx.cache.inlined_items.insert(ori_res_did);
|
||||
}
|
||||
inlined
|
||||
}
|
||||
@ -483,7 +496,6 @@ fn visit_item_inner(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user