提交 764b8615 编写于 作者: B bors

Auto merge of #97433 - GuillaumeGomez:rm-refcell-context, r=notriddle

Pass Context as a &mut to allow to remove RefCell fields

Fixes #90323.

r? `@notriddle`
......@@ -55,9 +55,9 @@ pub(crate) struct Context<'tcx> {
pub(super) render_redirect_pages: bool,
/// Tracks section IDs for `Deref` targets so they match in both the main
/// body and the sidebar.
pub(super) deref_id_map: RefCell<FxHashMap<DefId, String>>,
pub(super) deref_id_map: FxHashMap<DefId, String>,
/// The map used to ensure all generated 'id=' attributes are unique.
pub(super) id_map: RefCell<IdMap>,
pub(super) id_map: IdMap,
/// Shared mutable state.
///
/// Issue for improving the situation: [#82381][]
......@@ -72,7 +72,7 @@ pub(crate) struct Context<'tcx> {
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Context<'_>, 144);
rustc_data_structures::static_assert_size!(Context<'_>, 128);
/// Shared mutable state used in [`Context`] and elsewhere.
pub(crate) struct SharedContext<'tcx> {
......@@ -155,9 +155,8 @@ pub(super) fn sess(&self) -> &'tcx Session {
self.shared.tcx.sess
}
pub(super) fn derive_id(&self, id: String) -> String {
let mut map = self.id_map.borrow_mut();
map.derive(id)
pub(super) fn derive_id(&mut self, id: String) -> String {
self.id_map.derive(id)
}
/// String representation of how to get back to the root path of the 'doc/'
......@@ -166,7 +165,7 @@ pub(super) fn root_path(&self) -> String {
"../".repeat(self.current.len())
}
fn render_item(&self, it: &clean::Item, is_module: bool) -> String {
fn render_item(&mut self, it: &clean::Item, is_module: bool) -> String {
let mut title = String::new();
if !is_module {
title.push_str(it.name.unwrap().as_str());
......@@ -203,23 +202,26 @@ fn render_item(&self, it: &clean::Item, is_module: bool) -> String {
};
if !self.render_redirect_pages {
let clone_shared = Rc::clone(&self.shared);
let page = layout::Page {
css_class: tyname_s,
root_path: &self.root_path(),
static_root_path: self.shared.static_root_path.as_deref(),
static_root_path: clone_shared.static_root_path.as_deref(),
title: &title,
description: &desc,
keywords: &keywords,
resource_suffix: &self.shared.resource_suffix,
resource_suffix: &clone_shared.resource_suffix,
extra_scripts: &[],
static_extra_scripts: &[],
};
let mut page_buffer = Buffer::html();
print_item(self, it, &mut page_buffer, &page);
layout::render(
&self.shared.layout,
&clone_shared.layout,
&page,
|buf: &mut _| print_sidebar(self, it, buf),
|buf: &mut _| print_item(self, it, buf, &page),
&self.shared.style_files,
move |buf: &mut Buffer| buf.push_buffer(page_buffer),
&clone_shared.style_files,
)
} else {
if let Some(&(ref names, ty)) = self.cache().paths.get(&it.item_id.expect_def_id()) {
......@@ -512,8 +514,8 @@ fn init(
current: Vec::new(),
dst,
render_redirect_pages: false,
id_map: RefCell::new(id_map),
deref_id_map: RefCell::new(FxHashMap::default()),
id_map,
deref_id_map: FxHashMap::default(),
shared: Rc::new(scx),
include_sources,
};
......@@ -528,7 +530,7 @@ fn init(
// Write shared runs within a flock; disable thread dispatching of IO temporarily.
Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true);
write_shared(&cx, &krate, index, &md_opts)?;
write_shared(&mut cx, &krate, index, &md_opts)?;
Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
}
......@@ -540,8 +542,8 @@ fn make_child_renderer(&self) -> Self {
current: self.current.clone(),
dst: self.dst.clone(),
render_redirect_pages: self.render_redirect_pages,
deref_id_map: RefCell::new(FxHashMap::default()),
id_map: RefCell::new(IdMap::new()),
deref_id_map: FxHashMap::default(),
id_map: IdMap::new(),
shared: Rc::clone(&self.shared),
include_sources: self.include_sources,
}
......@@ -557,31 +559,32 @@ fn after_krate(&mut self) -> Result<(), Error> {
if !root_path.ends_with('/') {
root_path.push('/');
}
let shared = Rc::clone(&self.shared);
let mut page = layout::Page {
title: "List of all items in this crate",
css_class: "mod",
root_path: "../",
static_root_path: self.shared.static_root_path.as_deref(),
static_root_path: shared.static_root_path.as_deref(),
description: "List of all items in this crate",
keywords: BASIC_KEYWORDS,
resource_suffix: &self.shared.resource_suffix,
resource_suffix: &shared.resource_suffix,
extra_scripts: &[],
static_extra_scripts: &[],
};
let sidebar = if self.shared.cache.crate_version.is_some() {
let sidebar = if shared.cache.crate_version.is_some() {
format!("<h2 class=\"location\">Crate {}</h2>", crate_name)
} else {
String::new()
};
let all = self.shared.all.replace(AllTypes::new());
let all = shared.all.replace(AllTypes::new());
let v = layout::render(
&self.shared.layout,
&shared.layout,
&page,
sidebar,
|buf: &mut Buffer| all.print(buf),
&self.shared.style_files,
&shared.style_files,
);
self.shared.fs.write(final_file, v)?;
shared.fs.write(final_file, v)?;
// Generating settings page.
page.title = "Rustdoc settings";
......@@ -590,7 +593,7 @@ fn after_krate(&mut self) -> Result<(), Error> {
let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
let v = layout::render(
&self.shared.layout,
&shared.layout,
&page,
sidebar,
|buf: &mut Buffer| {
......@@ -613,33 +616,36 @@ fn after_krate(&mut self) -> Result<(), Error> {
suffix = page.resource_suffix,
)
},
&self.shared.style_files,
&shared.style_files,
);
self.shared.fs.write(settings_file, v)?;
shared.fs.write(settings_file, v)?;
if self.shared.layout.scrape_examples_extension {
if shared.layout.scrape_examples_extension {
page.title = "About scraped examples";
page.description = "How the scraped examples feature works in Rustdoc";
let v = layout::render(
&self.shared.layout,
&shared.layout,
&page,
"",
scrape_examples_help(&*self.shared),
&self.shared.style_files,
scrape_examples_help(&*shared),
&shared.style_files,
);
self.shared.fs.write(scrape_examples_help_file, v)?;
shared.fs.write(scrape_examples_help_file, v)?;
}
if let Some(ref redirections) = self.shared.redirections {
if let Some(ref redirections) = shared.redirections {
if !redirections.borrow().is_empty() {
let redirect_map_path =
self.dst.join(crate_name.as_str()).join("redirect-map.json");
let paths = serde_json::to_string(&*redirections.borrow()).unwrap();
self.shared.ensure_dir(&self.dst.join(crate_name.as_str()))?;
self.shared.fs.write(redirect_map_path, paths)?;
shared.ensure_dir(&self.dst.join(crate_name.as_str()))?;
shared.fs.write(redirect_map_path, paths)?;
}
}
// No need for it anymore.
drop(shared);
// Flush pending errors.
Rc::get_mut(&mut self.shared).unwrap().fs.close();
let nb_errors =
......@@ -662,7 +668,6 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
if !self.render_redirect_pages {
self.render_redirect_pages = item.is_stripped();
}
let scx = &self.shared;
let item_name = item.name.unwrap();
self.dst.push(&*item_name.as_str());
self.current.push(item_name);
......@@ -674,7 +679,7 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
if !buf.is_empty() {
self.shared.ensure_dir(&self.dst)?;
let joint_dst = self.dst.join("index.html");
scx.fs.write(joint_dst, buf)?;
self.shared.fs.write(joint_dst, buf)?;
}
// Render sidebar-items.js used throughout this module.
......@@ -684,7 +689,7 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
let items = self.build_sidebar_items(module);
let js_dst = self.dst.join(&format!("sidebar-items{}.js", self.shared.resource_suffix));
let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap());
scx.fs.write(js_dst, v)?;
self.shared.fs.write(js_dst, v)?;
}
Ok(())
}
......
......@@ -42,6 +42,7 @@
use std::fs;
use std::iter::Peekable;
use std::path::PathBuf;
use std::rc::Rc;
use std::str;
use std::string::ToString;
......@@ -364,7 +365,7 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
fn document(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
item: &clean::Item,
parent: Option<&clean::Item>,
heading_offset: HeadingOffset,
......@@ -383,19 +384,18 @@ fn document(
/// Render md_text as markdown.
fn render_markdown(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
md_text: &str,
links: Vec<RenderedLink>,
heading_offset: HeadingOffset,
) {
let mut ids = cx.id_map.borrow_mut();
write!(
w,
"<div class=\"docblock\">{}</div>",
Markdown {
content: md_text,
links: &links,
ids: &mut ids,
ids: &mut cx.id_map,
error_codes: cx.shared.codes,
edition: cx.shared.edition(),
playground: &cx.shared.playground,
......@@ -410,7 +410,7 @@ fn render_markdown(
fn document_short(
w: &mut Buffer,
item: &clean::Item,
cx: &Context<'_>,
cx: &mut Context<'_>,
link: AssocItemLink<'_>,
parent: &clean::Item,
show_def_docs: bool,
......@@ -439,7 +439,7 @@ fn document_short(
fn document_full_collapsible(
w: &mut Buffer,
item: &clean::Item,
cx: &Context<'_>,
cx: &mut Context<'_>,
heading_offset: HeadingOffset,
) {
document_full_inner(w, item, cx, true, heading_offset);
......@@ -448,7 +448,7 @@ fn document_full_collapsible(
fn document_full(
w: &mut Buffer,
item: &clean::Item,
cx: &Context<'_>,
cx: &mut Context<'_>,
heading_offset: HeadingOffset,
) {
document_full_inner(w, item, cx, false, heading_offset);
......@@ -457,7 +457,7 @@ fn document_full(
fn document_full_inner(
w: &mut Buffer,
item: &clean::Item,
cx: &Context<'_>,
cx: &mut Context<'_>,
is_collapsible: bool,
heading_offset: HeadingOffset,
) {
......@@ -493,7 +493,7 @@ fn document_full_inner(
/// * Required features (through the `doc_cfg` feature)
fn document_item_info(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
item: &clean::Item,
parent: Option<&clean::Item>,
) {
......@@ -522,7 +522,7 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<Strin
/// the item's documentation.
fn short_item_info(
item: &clean::Item,
cx: &Context<'_>,
cx: &mut Context<'_>,
parent: Option<&clean::Item>,
) -> Vec<String> {
let mut extra_info = vec![];
......@@ -550,10 +550,9 @@ fn short_item_info(
if let Some(note) = note {
let note = note.as_str();
let mut ids = cx.id_map.borrow_mut();
let html = MarkdownHtml(
note,
&mut ids,
&mut cx.id_map,
error_codes,
cx.shared.edition(),
&cx.shared.playground,
......@@ -601,7 +600,7 @@ fn short_item_info(
// Render the list of items inside one of the sections "Trait Implementations",
// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
fn render_impls(
cx: &Context<'_>,
cx: &mut Context<'_>,
w: &mut Buffer,
impls: &[&&Impl],
containing_item: &clean::Item,
......@@ -994,7 +993,7 @@ fn anchor(&self, id: &'a str) -> Self {
fn render_assoc_items(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
containing_item: &clean::Item,
it: DefId,
what: AssocItemRender<'_>,
......@@ -1006,14 +1005,15 @@ fn render_assoc_items(
fn render_assoc_items_inner(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
containing_item: &clean::Item,
it: DefId,
what: AssocItemRender<'_>,
derefs: &mut FxHashSet<DefId>,
) {
info!("Documenting associated items of {:?}", containing_item.name);
let cache = cx.cache();
let shared = Rc::clone(&cx.shared);
let cache = &shared.cache;
let Some(v) = cache.impls.get(&it) else { return };
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
if !non_trait.is_empty() {
......@@ -1032,7 +1032,7 @@ fn render_assoc_items_inner(
let id =
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
if let Some(def_id) = type_.def_id(cx.cache()) {
cx.deref_id_map.borrow_mut().insert(def_id, id.clone());
cx.deref_id_map.insert(def_id, id.clone());
}
write!(
tmp_buf,
......@@ -1138,7 +1138,7 @@ fn render_assoc_items_inner(
fn render_deref_methods(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
impl_: &Impl,
container_item: &clean::Item,
deref_mut: bool,
......@@ -1285,7 +1285,7 @@ struct ImplRenderingParameters {
fn render_impl(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
i: &Impl,
parent: &clean::Item,
link: AssocItemLink<'_>,
......@@ -1294,7 +1294,8 @@ fn render_impl(
aliases: &[String],
rendering_params: ImplRenderingParameters,
) {
let cache = cx.cache();
let shared = Rc::clone(&cx.shared);
let cache = &shared.cache;
let traits = &cache.traits;
let trait_ = i.trait_did().map(|did| &traits[&did]);
let mut close_tags = String::new();
......@@ -1307,7 +1308,7 @@ fn render_impl(
fn doc_impl_item(
boring: &mut Buffer,
interesting: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
item: &clean::Item,
parent: &clean::Item,
containing_item: &clean::Item,
......@@ -1520,7 +1521,7 @@ fn doc_impl_item(
fn render_default_items(
boring: &mut Buffer,
interesting: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
t: &clean::Trait,
i: &clean::Impl,
parent: &clean::Item,
......@@ -1599,14 +1600,13 @@ fn render_default_items(
}
if let Some(ref dox) = i.impl_item.collapsed_doc_value() {
let mut ids = cx.id_map.borrow_mut();
write!(
w,
"<div class=\"docblock\">{}</div>",
Markdown {
content: &*dox,
links: &i.impl_item.links(cx),
ids: &mut ids,
ids: &mut cx.id_map,
error_codes: cx.shared.codes,
edition: cx.shared.edition(),
playground: &cx.shared.playground,
......@@ -1664,7 +1664,7 @@ fn render_rightside(
pub(crate) fn render_impl_summary(
w: &mut Buffer,
cx: &Context<'_>,
cx: &mut Context<'_>,
i: &Impl,
parent: &clean::Item,
containing_item: &clean::Item,
......@@ -2092,10 +2092,8 @@ fn sidebar_deref_methods(
})
.collect::<Vec<_>>();
if !ret.is_empty() {
let map;
let id = if let Some(target_def_id) = real_target.def_id(c) {
map = cx.deref_id_map.borrow();
map.get(&target_def_id).expect("Deref section without derived id")
cx.deref_id_map.get(&target_def_id).expect("Deref section without derived id")
} else {
"deref-methods"
};
......@@ -2641,14 +2639,14 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
const NUM_VISIBLE_LINES: usize = 10;
/// Generates the HTML for example call locations generated via the --scrape-examples flag.
fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item) {
let tcx = cx.tcx();
let def_id = item.item_id.expect_def_id();
let key = tcx.def_path_hash(def_id);
let Some(call_locations) = cx.shared.call_locations.get(&key) else { return };
// Generate a unique ID so users can link to this section for a given method
let id = cx.id_map.borrow_mut().derive("scraped-examples");
let id = cx.id_map.derive("scraped-examples");
write!(
w,
"<div class=\"docblock scraped-example-list\">\
......
......@@ -2,6 +2,7 @@
use std::cmp::Ordering;
use std::fmt;
use std::rc::Rc;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
......@@ -60,7 +61,12 @@ struct ItemVars<'a> {
src_href: Option<&'a str>,
}
pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
pub(super) fn print_item(
cx: &mut Context<'_>,
item: &clean::Item,
buf: &mut Buffer,
page: &Page<'_>,
) {
debug_assert!(!item.is_stripped());
let typ = match *item.kind {
clean::ModuleItem(_) => {
......@@ -187,7 +193,7 @@ fn toggle_close(w: &mut Buffer) {
w.write_str("</details>");
}
fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) {
fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: &[clean::Item]) {
document(w, cx, item, None, HeadingOffset::H2);
let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::<Vec<usize>>();
......@@ -344,6 +350,12 @@ fn cmp(
let add = if stab.is_some() { " " } else { "" };
w.write_str(ITEM_TABLE_ROW_OPEN);
let id = match import.kind {
clean::ImportKind::Simple(s) => {
format!(" id=\"{}\"", cx.derive_id(format!("reexport.{}", s)))
}
clean::ImportKind::Glob => String::new(),
};
write!(
w,
"<div class=\"item-left {stab}{add}import-item\"{id}>\
......@@ -351,15 +363,9 @@ fn cmp(
</div>\
<div class=\"item-right docblock-short\">{stab_tags}</div>",
stab = stab.unwrap_or_default(),
add = add,
vis = myitem.visibility.print_with_space(myitem.item_id, cx),
imp = import.print(cx),
stab_tags = stab_tags.unwrap_or_default(),
id = match import.kind {
clean::ImportKind::Simple(s) =>
format!(" id=\"{}\"", cx.derive_id(format!("reexport.{}", s))),
clean::ImportKind::Glob => String::new(),
},
);
w.write_str(ITEM_TABLE_ROW_CLOSE);
}
......@@ -464,7 +470,7 @@ fn tag_html(class: &str, title: &str, contents: &str) -> String {
tags
}
fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &clean::Function) {
let header = it.fn_header(cx.tcx()).expect("printing a function which isn't a function");
let constness = print_constness_with_space(&header.constness, it.const_stability(cx.tcx()));
let unsafety = header.unsafety.print_with_space();
......@@ -507,7 +513,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
document(w, cx, it, None, HeadingOffset::H2)
}
fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) {
fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) {
let bounds = bounds(&t.bounds, false, cx);
let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::<Vec<_>>();
let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
......@@ -674,7 +680,7 @@ fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_conte
)
}
fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item) {
fn trait_item(w: &mut Buffer, cx: &mut Context<'_>, m: &clean::Item, t: &clean::Item) {
let name = m.name.unwrap();
info!("Documenting {} on {:?}", name, t.name);
let item_type = m.type_();
......@@ -791,14 +797,15 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
// If there are methods directly on this trait object, render them here.
render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All);
let cache = cx.cache();
let cloned_shared = Rc::clone(&cx.shared);
let cache = &cloned_shared.cache;
let mut extern_crates = FxHashSet::default();
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
// The DefId is for the first Type found with that name. The bool is
// if any Types with the same name but different DefId have been found.
let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
for implementor in implementors {
if let Some(did) = implementor.inner_impl().for_.without_borrowed_ref().def_id(cx.cache()) &&
if let Some(did) = implementor.inner_impl().for_.without_borrowed_ref().def_id(cache) &&
!did.is_local() {
extern_crates.insert(did.krate);
}
......@@ -996,7 +1003,7 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
);
}
fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
wrap_into_docblock(w, |w| {
wrap_item(w, "trait-alias", |w| {
render_attributes_in_pre(w, it, "");
......@@ -1020,7 +1027,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All)
}
fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
fn item_opaque_ty(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
wrap_into_docblock(w, |w| {
wrap_item(w, "opaque", |w| {
render_attributes_in_pre(w, it, "");
......@@ -1044,7 +1051,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean:
render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All)
}
fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Typedef) {
fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
wrap_item(w, "typedef", |w| {
render_attributes_in_pre(w, it, "");
......@@ -1073,7 +1080,7 @@ fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::
document_type_layout(w, cx, def_id);
}
fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) {
fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Union) {
wrap_into_docblock(w, |w| {
wrap_item(w, "union", |w| {
render_attributes_in_pre(w, it, "");
......@@ -1135,7 +1142,7 @@ fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item]
}
}
fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) {
fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) {
let count_variants = e.variants().count();
wrap_into_docblock(w, |w| {
wrap_item(w, "enum", |w| {
......@@ -1283,7 +1290,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
document_type_layout(w, cx, def_id);
}
fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) {
fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) {
wrap_into_docblock(w, |w| {
highlight::render_with_highlighting(
&t.source,
......@@ -1300,7 +1307,7 @@ fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Mac
document(w, cx, it, None, HeadingOffset::H2)
}
fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
fn item_proc_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
wrap_into_docblock(w, |w| {
let name = it.name.expect("proc-macros always have names");
match m.kind {
......@@ -1332,12 +1339,12 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean
document(w, cx, it, None, HeadingOffset::H2)
}
fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
document(w, cx, it, None, HeadingOffset::H2);
render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All)
}
fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) {
wrap_into_docblock(w, |w| {
wrap_item(w, "const", |w| {
render_attributes_in_code(w, it);
......@@ -1377,7 +1384,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::
document(w, cx, it, None, HeadingOffset::H2)
}
fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) {
fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Struct) {
wrap_into_docblock(w, |w| {
wrap_item(w, "struct", |w| {
render_attributes_in_code(w, it);
......@@ -1430,7 +1437,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
document_type_layout(w, cx, def_id);
}
fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Static) {
wrap_into_docblock(w, |w| {
wrap_item(w, "static", |w| {
render_attributes_in_code(w, it);
......@@ -1447,7 +1454,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
document(w, cx, it, None, HeadingOffset::H2)
}
fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
wrap_into_docblock(w, |w| {
wrap_item(w, "foreigntype", |w| {
w.write_str("extern {\n");
......@@ -1466,7 +1473,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All)
}
fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
fn item_keyword(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
document(w, cx, it, None, HeadingOffset::H2)
}
......@@ -1579,7 +1586,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl, cx: &Context<'_>) -> O
}
fn render_implementor(
cx: &Context<'_>,
cx: &mut Context<'_>,
implementor: &Impl,
trait_: &clean::Item,
w: &mut Buffer,
......
......@@ -5,6 +5,7 @@
use std::io::{self, BufReader};
use std::lazy::SyncLazy as Lazy;
use std::path::{Component, Path, PathBuf};
use std::rc::Rc;
use itertools::Itertools;
use rustc_data_structures::flock;
......@@ -135,7 +136,7 @@ fn write_minify(
}
pub(super) fn write_shared(
cx: &Context<'_>,
cx: &mut Context<'_>,
krate: &Crate,
search_index: String,
options: &RenderOptions,
......@@ -462,15 +463,16 @@ fn to_json_string(&self) -> String {
crate::markdown::render(&index_page, md_opts, cx.shared.edition())
.map_err(|e| Error::new(e, &index_page))?;
} else {
let shared = Rc::clone(&cx.shared);
let dst = cx.dst.join("index.html");
let page = layout::Page {
title: "Index of crates",
css_class: "mod",
root_path: "./",
static_root_path: cx.shared.static_root_path.as_deref(),
static_root_path: shared.static_root_path.as_deref(),
description: "List of crates",
keywords: BASIC_KEYWORDS,
resource_suffix: &cx.shared.resource_suffix,
resource_suffix: &shared.resource_suffix,
extra_scripts: &[],
static_extra_scripts: &[],
};
......@@ -490,8 +492,8 @@ fn to_json_string(&self) -> String {
})
.collect::<String>()
);
let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.style_files);
cx.shared.fs.write(dst, v)?;
let v = layout::render(&shared.layout, &page, "", content, &shared.style_files);
shared.fs.write(dst, v)?;
}
}
......
......@@ -6,15 +6,18 @@
use crate::html::layout;
use crate::html::render::{Context, BASIC_KEYWORDS};
use crate::visit::DocVisitor;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::source_map::FileName;
use std::ffi::OsStr;
use std::fs;
use std::path::{Component, Path, PathBuf};
use std::rc::Rc;
pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> {
info!("emitting source files");
......@@ -174,15 +177,16 @@ fn emit_source(
// Remove the utf-8 BOM if any
let contents = contents.strip_prefix('\u{feff}').unwrap_or(&contents);
let shared = Rc::clone(&self.cx.shared);
// Create the intermediate directories
let mut cur = self.dst.clone();
let mut root_path = String::from("../../");
clean_path(&self.cx.shared.src_root, &p, false, |component| {
clean_path(&shared.src_root, &p, false, |component| {
cur.push(component);
root_path.push_str("../");
});
self.cx.shared.ensure_dir(&cur)?;
shared.ensure_dir(&cur)?;
let src_fname = p.file_name().expect("source has no filename").to_os_string();
let mut fname = src_fname.clone();
......@@ -195,32 +199,33 @@ fn emit_source(
title: &title,
css_class: "source",
root_path: &root_path,
static_root_path: self.cx.shared.static_root_path.as_deref(),
static_root_path: shared.static_root_path.as_deref(),
description: &desc,
keywords: BASIC_KEYWORDS,
resource_suffix: &self.cx.shared.resource_suffix,
extra_scripts: &[&format!("source-files{}", self.cx.shared.resource_suffix)],
static_extra_scripts: &[&format!("source-script{}", self.cx.shared.resource_suffix)],
resource_suffix: &shared.resource_suffix,
extra_scripts: &[&format!("source-files{}", shared.resource_suffix)],
static_extra_scripts: &[&format!("source-script{}", shared.resource_suffix)],
};
let v = layout::render(
&self.cx.shared.layout,
&shared.layout,
&page,
"",
|buf: &mut _| {
let cx = &mut self.cx;
print_src(
buf,
contents,
self.cx.shared.edition(),
cx.shared.edition(),
file_span,
self.cx,
cx,
&root_path,
None,
SourceContext::Standalone,
)
},
&self.cx.shared.style_files,
&shared.style_files,
);
self.cx.shared.fs.write(cur, v)?;
shared.fs.write(cur, v)?;
self.emitted_local_sources.insert(p);
Ok(())
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册