diff options
Diffstat (limited to 'src/librustdoc/html/render')
| -rw-r--r-- | src/librustdoc/html/render/context.rs | 28 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 37 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 124 | ||||
| -rw-r--r-- | src/librustdoc/html/render/search_index.rs | 9 | ||||
| -rw-r--r-- | src/librustdoc/html/render/span_map.rs | 2 | 
5 files changed, 113 insertions, 87 deletions
| diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index e4fca09d64f..faaecaf0cbb 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefIdMap, LOCAL_CRATE}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; -use rustc_span::{FileName, Symbol, sym}; +use rustc_span::{BytePos, FileName, Symbol, sym}; use tracing::info; use super::print_item::{full_path, print_item, print_item_path}; @@ -28,6 +28,7 @@ use crate::formats::FormatRenderer; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; +use crate::html::macro_expansion::ExpandedCode; use crate::html::markdown::{self, ErrorCodes, IdMap, plain_text_summary}; use crate::html::render::write_shared::write_shared; use crate::html::url_parts_builder::UrlPartsBuilder; @@ -139,6 +140,7 @@ pub(crate) struct SharedContext<'tcx> { /// Correspondence map used to link types used in the source code pages to allow to click on /// links to jump to the type's definition. pub(crate) span_correspondence_map: FxHashMap<rustc_span::Span, LinkFromSrc>, + pub(crate) expanded_codes: FxHashMap<BytePos, Vec<ExpandedCode>>, /// The [`Cache`] used during rendering. pub(crate) cache: Cache, pub(crate) call_locations: AllCallLocations, @@ -458,20 +460,13 @@ impl<'tcx> Context<'tcx> { } } -/// Generates the documentation for `crate` into the directory `dst` -impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { - fn descr() -> &'static str { - "html" - } - - const RUN_ON_MODULE: bool = true; - type ModuleData = ContextInfo; - - fn init( +impl<'tcx> Context<'tcx> { + pub(crate) fn init( krate: clean::Crate, options: RenderOptions, cache: Cache, tcx: TyCtxt<'tcx>, + expanded_codes: FxHashMap<BytePos, Vec<ExpandedCode>>, ) -> Result<(Self, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); @@ -579,6 +574,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { cache, call_locations, should_merge: options.should_merge, + expanded_codes, }; let dst = output; @@ -604,6 +600,16 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { Ok((cx, krate)) } +} + +/// Generates the documentation for `crate` into the directory `dst` +impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { + fn descr() -> &'static str { + "html" + } + + const RUN_ON_MODULE: bool = true; + type ModuleData = ContextInfo; fn save_module_data(&mut self) -> Self::ModuleData { self.deref_id_map.borrow_mut().clear(); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8d7f0577506..673947ad308 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1029,6 +1029,7 @@ fn assoc_const( ) -> impl fmt::Display { let tcx = cx.tcx(); fmt::from_fn(move |w| { + render_attributes_in_code(w, it, &" ".repeat(indent), cx); write!( w, "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}", @@ -1136,10 +1137,10 @@ fn assoc_method( let (indent, indent_str, end_newline) = if parent == ItemType::Trait { header_len += 4; let indent_str = " "; - write!(w, "{}", render_attributes_in_pre(meth, indent_str, cx))?; + render_attributes_in_code(w, meth, indent_str, cx); (4, indent_str, Ending::NoNewline) } else { - render_attributes_in_code(w, meth, cx); + render_attributes_in_code(w, meth, "", cx); (0, "", Ending::Newline) }; write!( @@ -1309,28 +1310,28 @@ fn render_assoc_item( }) } -// When an attribute is rendered inside a `<pre>` tag, it is formatted using -// a whitespace prefix and newline. -fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display { - fmt::from_fn(move |f| { - for a in it.attributes(cx.tcx(), cx.cache()) { - writeln!(f, "{prefix}{a}")?; - } - Ok(()) - }) -} - struct CodeAttribute(String); -fn render_code_attribute(code_attr: CodeAttribute, w: &mut impl fmt::Write) { - write!(w, "<div class=\"code-attribute\">{}</div>", code_attr.0).unwrap(); +fn render_code_attribute(prefix: &str, code_attr: CodeAttribute, w: &mut impl fmt::Write) { + write!( + w, + "<div class=\"code-attribute\">{prefix}{attr}</div>", + prefix = prefix, + attr = code_attr.0 + ) + .unwrap(); } // When an attribute is rendered inside a <code> tag, it is formatted using // a div to produce a newline after it. -fn render_attributes_in_code(w: &mut impl fmt::Write, it: &clean::Item, cx: &Context<'_>) { +fn render_attributes_in_code( + w: &mut impl fmt::Write, + it: &clean::Item, + prefix: &str, + cx: &Context<'_>, +) { for attr in it.attributes(cx.tcx(), cx.cache()) { - render_code_attribute(CodeAttribute(attr), w); + render_code_attribute(prefix, CodeAttribute(attr), w); } } @@ -1342,7 +1343,7 @@ fn render_repr_attributes_in_code( item_type: ItemType, ) { if let Some(repr) = clean::repr_attributes(cx.tcx(), cx.cache(), def_id, item_type) { - render_code_attribute(CodeAttribute(repr), w); + render_code_attribute("", CodeAttribute(repr), w); } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 407238d66b8..b86a2c94697 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -20,8 +20,8 @@ use super::{ AssocItemLink, AssocItemRender, Context, ImplRenderingParameters, RenderMode, collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference, item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls, - render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre, - render_impl, render_repr_attributes_in_code, render_rightside, render_stability_since_raw, + render_assoc_item, render_assoc_items, render_attributes_in_code, render_impl, + render_repr_attributes_in_code, render_rightside, render_stability_since_raw, render_stability_since_raw_with_extra, write_section_heading, }; use crate::clean; @@ -107,13 +107,6 @@ macro_rules! item_template_methods { } item_template_methods!($($rest)*); }; - (render_attributes_in_pre $($rest:tt)*) => { - fn render_attributes_in_pre(&self) -> impl fmt::Display { - let (item, cx) = self.item_and_cx(); - render_attributes_in_pre(item, "", cx) - } - item_template_methods!($($rest)*); - }; (render_assoc_items $($rest:tt)*) => { fn render_assoc_items(&self) -> impl fmt::Display { let (item, cx) = self.item_and_cx(); @@ -457,7 +450,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i write!( w, "<dt{id}>\ - <code>{vis}{imp}</code>{stab_tags}\ + <code>" + )?; + render_attributes_in_code(w, myitem, "", cx); + write!( + w, + "{vis}{imp}</code>{stab_tags}\ </dt>", vis = visibility_print_with_space(myitem, cx), imp = import.print(cx) @@ -625,11 +623,11 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display(); wrap_item(w, |w| { + render_attributes_in_code(w, it, "", cx); write!( w, - "{attrs}{vis}{constness}{asyncness}{safety}{abi}fn \ + "{vis}{constness}{asyncness}{safety}{abi}fn \ {name}{generics}{decl}{notable_traits}{where_clause}", - attrs = render_attributes_in_pre(it, "", cx), vis = visibility, constness = constness, asyncness = asyncness, @@ -666,10 +664,10 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: // Output the trait definition wrap_item(w, |mut w| { + render_attributes_in_code(&mut w, it, "", cx); write!( w, - "{attrs}{vis}{safety}{is_auto}trait {name}{generics}{bounds}", - attrs = render_attributes_in_pre(it, "", cx), + "{vis}{safety}{is_auto}trait {name}{generics}{bounds}", vis = visibility_print_with_space(it, cx), safety = t.safety(tcx).print_with_space(), is_auto = if t.is_auto(tcx) { "auto " } else { "" }, @@ -1240,10 +1238,10 @@ fn item_trait_alias( ) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { + render_attributes_in_code(w, it, "", cx); write!( w, - "{attrs}trait {name}{generics} = {bounds}{where_clause};", - attrs = render_attributes_in_pre(it, "", cx), + "trait {name}{generics} = {bounds}{where_clause};", name = it.name.unwrap(), generics = t.generics.print(cx), bounds = print_bounds(&t.bounds, true, cx), @@ -1268,10 +1266,10 @@ fn item_trait_alias( fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { + render_attributes_in_code(w, it, "", cx); write!( w, - "{attrs}{vis}type {name}{generics}{where_clause} = {type_};", - attrs = render_attributes_in_pre(it, "", cx), + "{vis}type {name}{generics}{where_clause} = {type_};", vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), generics = t.generics.print(cx), @@ -1452,7 +1450,21 @@ item_template!( impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { fn render_union(&self) -> impl Display { - render_union(self.it, Some(self.generics), self.fields, self.cx) + render_union( + self.it, + Some(self.generics), + self.fields, + self.def_id, + self.is_type_alias, + self.cx, + ) + } + + fn print_field_attrs(&self, field: &'a clean::Item) -> impl Display { + fmt::from_fn(move |w| { + render_attributes_in_code(w, field, "", self.cx); + Ok(()) + }) } fn document_field(&self, field: &'a clean::Item) -> impl Display { @@ -1479,27 +1491,6 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { _ => None, }) } - - fn render_attributes_in_pre(&self) -> impl fmt::Display { - fmt::from_fn(move |f| { - if self.is_type_alias { - // For now the only attributes we render for type aliases are `repr` attributes. - if let Some(repr) = clean::repr_attributes( - self.cx.tcx(), - self.cx.cache(), - self.def_id, - ItemType::Union, - ) { - writeln!(f, "{repr}")?; - }; - } else { - for a in self.it.attributes(self.cx.tcx(), self.cx.cache()) { - writeln!(f, "{a}")?; - } - } - Ok(()) - }) - } } fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display { @@ -1563,7 +1554,7 @@ impl<'clean> DisplayEnum<'clean> { // For now the only attributes we render for type aliases are `repr` attributes. render_repr_attributes_in_code(w, cx, self.def_id, ItemType::Enum); } else { - render_attributes_in_code(w, it, cx); + render_attributes_in_code(w, it, "", cx); } write!( w, @@ -1702,7 +1693,7 @@ fn render_enum_fields( if v.is_stripped() { continue; } - write!(w, "{}", render_attributes_in_pre(v, TAB, cx))?; + render_attributes_in_code(w, v, TAB, cx); w.write_str(TAB)?; match v.kind { clean::VariantItem(ref var) => match var.kind { @@ -1786,6 +1777,7 @@ fn item_variants( ) .maybe_display() )?; + render_attributes_in_code(w, variant, "", cx); if let clean::VariantItem(ref var) = variant.kind && let clean::VariantKind::CLike = var.kind { @@ -1859,7 +1851,12 @@ fn item_variants( "<div class=\"sub-variant-field\">\ <span id=\"{id}\" class=\"section-header\">\ <a href=\"#{id}\" class=\"anchor field\">§</a>\ - <code>{f}: {t}</code>\ + <code>" + )?; + render_attributes_in_code(w, field, "", cx); + write!( + w, + "{f}: {t}</code>\ </span>\ {doc}\ </div>", @@ -1882,6 +1879,7 @@ fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt: fmt::from_fn(|w| { wrap_item(w, |w| { // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. + render_attributes_in_code(w, it, "", cx); if !t.macro_rules { write!(w, "{}", visibility_print_with_space(it, cx))?; } @@ -1950,7 +1948,7 @@ fn item_constant( fmt::from_fn(|w| { wrap_item(w, |w| { let tcx = cx.tcx(); - render_attributes_in_code(w, it, cx); + render_attributes_in_code(w, it, "", cx); write!( w, @@ -2018,7 +2016,7 @@ impl<'a> DisplayStruct<'a> { // For now the only attributes we render for type aliases are `repr` attributes. render_repr_attributes_in_code(w, cx, self.def_id, ItemType::Struct); } else { - render_attributes_in_code(w, it, cx); + render_attributes_in_code(w, it, "", cx); } write!( w, @@ -2094,10 +2092,15 @@ fn item_fields( w, "<span id=\"{id}\" class=\"{item_type} section-header\">\ <a href=\"#{id}\" class=\"anchor field\">§</a>\ - <code>{field_name}: {ty}</code>\ + <code>", + item_type = ItemType::StructField, + )?; + render_attributes_in_code(w, field, "", cx); + write!( + w, + "{field_name}: {ty}</code>\ </span>\ {doc}", - item_type = ItemType::StructField, ty = ty.print(cx), doc = document(cx, field, Some(it), HeadingOffset::H3), )?; @@ -2115,7 +2118,7 @@ fn item_static( ) -> impl fmt::Display { fmt::from_fn(move |w| { wrap_item(w, |w| { - render_attributes_in_code(w, it, cx); + render_attributes_in_code(w, it, "", cx); write!( w, "{vis}{safe}static {mutability}{name}: {typ}", @@ -2135,7 +2138,7 @@ fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { w.write_str("extern {\n")?; - render_attributes_in_code(w, it, cx); + render_attributes_in_code(w, it, "", cx); write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap(),) })?; @@ -2358,9 +2361,17 @@ fn render_union( it: &clean::Item, g: Option<&clean::Generics>, fields: &[clean::Item], + def_id: DefId, + is_type_alias: bool, cx: &Context<'_>, ) -> impl Display { fmt::from_fn(move |mut f| { + if is_type_alias { + // For now the only attributes we render for type aliases are `repr` attributes. + render_repr_attributes_in_code(f, cx, def_id, ItemType::Union); + } else { + render_attributes_in_code(f, it, "", cx); + } write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; let where_displayed = if let Some(generics) = g { @@ -2390,6 +2401,7 @@ fn render_union( for field in fields { if let clean::StructFieldItem(ref ty) = field.kind { + render_attributes_in_code(&mut f, field, " ", cx); writeln!( f, " {}{}: {},", @@ -2481,11 +2493,15 @@ fn render_struct_fields( if toggle { toggle_open(&mut *w, format_args!("{count_fields} fields")); } + if has_visible_fields { + writeln!(w)?; + } for field in fields { if let clean::StructFieldItem(ref ty) = field.kind { - write!( + render_attributes_in_code(w, field, &format!("{tab} "), cx); + writeln!( w, - "\n{tab} {vis}{name}: {ty},", + "{tab} {vis}{name}: {ty},", vis = visibility_print_with_space(field, cx), name = field.name.unwrap(), ty = ty.print(cx) @@ -2495,12 +2511,12 @@ fn render_struct_fields( if has_visible_fields { if has_stripped_entries { - write!( + writeln!( w, - "\n{tab} <span class=\"comment\">/* private fields */</span>" + "{tab} <span class=\"comment\">/* private fields */</span>" )?; } - write!(w, "\n{tab}")?; + write!(w, "{tab}")?; } else if has_stripped_entries { write!(w, " <span class=\"comment\">/* private fields */</span> ")?; } diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 41657e290ea..dddc087d124 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1494,7 +1494,9 @@ pub(crate) fn build_index( let search_unbox = match id { RenderTypeId::Mut => false, RenderTypeId::DefId(defid) => utils::has_doc_flag(tcx, defid, sym::search_unbox), - RenderTypeId::Primitive(PrimitiveType::Reference | PrimitiveType::Tuple) => true, + RenderTypeId::Primitive( + PrimitiveType::Reference | PrimitiveType::RawPointer | PrimitiveType::Tuple, + ) => true, RenderTypeId::Primitive(..) => false, RenderTypeId::AssociatedType(..) => false, // this bool is only used by `insert_into_map`, so it doesn't matter what we set here @@ -1855,7 +1857,7 @@ fn get_index_type_id( } clean::Primitive(p) => Some(RenderTypeId::Primitive(p)), clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)), - clean::RawPointer(_, ref type_) => get_index_type_id(type_, rgen), + clean::RawPointer { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::RawPointer)), // The type parameters are converted to generics in `simplify_fn_type` clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)), clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)), @@ -2113,7 +2115,8 @@ fn simplify_fn_type<'a, 'tcx>( generics: Some(ty_generics), }); } - Type::BorrowedRef { lifetime: _, mutability, ref type_ } => { + Type::BorrowedRef { lifetime: _, mutability, ref type_ } + | Type::RawPointer(mutability, ref type_) => { let mut ty_generics = Vec::new(); if mutability.is_mut() { ty_generics.push(RenderType { diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 846d3ad310c..8bc2e0bd957 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -35,7 +35,7 @@ pub(crate) enum LinkFromSrc { /// 1. Generate a `span` correspondence map which links an item `span` to its definition `span`. /// 2. Collect the source code files. /// -/// It returns the `krate`, the source code files and the `span` correspondence map. +/// It returns the source code files and the `span` correspondence map. /// /// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't /// need the `span` context later on, only their position, so instead of keeping a whole `Span`, we | 
