Fix invalid creation of files in rustdoc
This commit is contained in:
parent
bc20a8e01a
commit
db95734b9d
@ -121,6 +121,11 @@ pub(crate) struct Cache {
|
||||
pub(crate) intra_doc_links: FxHashMap<ItemId, FxIndexSet<clean::ItemLink>>,
|
||||
/// Cfg that have been hidden via #![doc(cfg_hide(...))]
|
||||
pub(crate) hidden_cfg: FxHashSet<clean::cfg::Cfg>,
|
||||
|
||||
/// Contains the list of `DefId`s which have been inlined. It is used when generating files
|
||||
/// to check if a stripped item should get its file generated or not: if it's inside a
|
||||
/// `#[doc(hidden)]` item or a private one and not inlined, it shouldn't get a file.
|
||||
pub(crate) inlined_items: DefIdSet,
|
||||
}
|
||||
|
||||
/// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`.
|
||||
|
@ -73,6 +73,8 @@ pub(crate) struct Context<'tcx> {
|
||||
pub(crate) include_sources: bool,
|
||||
/// Collection of all types with notable traits referenced in the current module.
|
||||
pub(crate) types_with_notable_traits: FxHashSet<clean::Type>,
|
||||
/// Field used during rendering, to know if we're inside an inlined item.
|
||||
pub(crate) is_inside_inlined_module: bool,
|
||||
}
|
||||
|
||||
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
|
||||
@ -171,6 +173,19 @@ impl<'tcx> Context<'tcx> {
|
||||
}
|
||||
|
||||
fn render_item(&mut self, it: &clean::Item, is_module: bool) -> String {
|
||||
let mut render_redirect_pages = self.render_redirect_pages;
|
||||
// If the item is stripped but inlined, links won't point to the item so no need to generate
|
||||
// a file for it.
|
||||
if it.is_stripped() &&
|
||||
let Some(def_id) = it.def_id() &&
|
||||
def_id.is_local()
|
||||
{
|
||||
if self.is_inside_inlined_module || self.shared.cache.inlined_items.contains(&def_id) {
|
||||
// For now we're forced to generate a redirect page for stripped items until
|
||||
// `record_extern_fqn` correctly points to external items.
|
||||
render_redirect_pages = true;
|
||||
}
|
||||
}
|
||||
let mut title = String::new();
|
||||
if !is_module {
|
||||
title.push_str(it.name.unwrap().as_str());
|
||||
@ -205,7 +220,7 @@ impl<'tcx> Context<'tcx> {
|
||||
tyname.as_str()
|
||||
};
|
||||
|
||||
if !self.render_redirect_pages {
|
||||
if !render_redirect_pages {
|
||||
let clone_shared = Rc::clone(&self.shared);
|
||||
let page = layout::Page {
|
||||
css_class: tyname_s,
|
||||
@ -545,6 +560,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
shared: Rc::new(scx),
|
||||
include_sources,
|
||||
types_with_notable_traits: FxHashSet::default(),
|
||||
is_inside_inlined_module: false,
|
||||
};
|
||||
|
||||
if emit_crate {
|
||||
@ -574,6 +590,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
shared: Rc::clone(&self.shared),
|
||||
include_sources: self.include_sources,
|
||||
types_with_notable_traits: FxHashSet::default(),
|
||||
is_inside_inlined_module: self.is_inside_inlined_module,
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,12 +785,22 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
|
||||
info!("Recursing into {}", self.dst.display());
|
||||
|
||||
let buf = self.render_item(item, true);
|
||||
// buf will be empty if the module is stripped and there is no redirect for it
|
||||
if !buf.is_empty() {
|
||||
self.shared.ensure_dir(&self.dst)?;
|
||||
let joint_dst = self.dst.join("index.html");
|
||||
self.shared.fs.write(joint_dst, buf)?;
|
||||
if !item.is_stripped() {
|
||||
let buf = self.render_item(item, true);
|
||||
// buf will be empty if the module is stripped and there is no redirect for it
|
||||
if !buf.is_empty() {
|
||||
self.shared.ensure_dir(&self.dst)?;
|
||||
let joint_dst = self.dst.join("index.html");
|
||||
self.shared.fs.write(joint_dst, buf)?;
|
||||
}
|
||||
}
|
||||
if !self.is_inside_inlined_module {
|
||||
if let Some(def_id) = item.def_id() && self.cache().inlined_items.contains(&def_id) {
|
||||
self.is_inside_inlined_module = true;
|
||||
}
|
||||
} else if item.is_doc_hidden() {
|
||||
// We're not inside an inlined module anymore since this one cannot be re-exported.
|
||||
self.is_inside_inlined_module = false;
|
||||
}
|
||||
|
||||
// Render sidebar-items.js used throughout this module.
|
||||
|
@ -313,7 +313,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
return false;
|
||||
}
|
||||
|
||||
let ret = match tcx.hir().get_by_def_id(res_did) {
|
||||
let inlined = match tcx.hir().get_by_def_id(res_did) {
|
||||
// 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.
|
||||
@ -344,7 +344,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
_ => false,
|
||||
};
|
||||
self.view_item_stack.remove(&res_did);
|
||||
ret
|
||||
if inlined {
|
||||
self.cx.cache.inlined_items.insert(res_did.to_def_id());
|
||||
}
|
||||
inlined
|
||||
}
|
||||
|
||||
/// Returns `true` if the item is visible, meaning it's not `#[doc(hidden)]` or private.
|
||||
|
Loading…
x
Reference in New Issue
Block a user