Skip to content

Commit 3ac32ca

Browse files
committed
rustdoc: make attributes render consistently
* make attributes render inside code elements and inside divs with class `code-attribute` * render attributes for macros, associated constants, and struct/union fields
1 parent f5703d5 commit 3ac32ca

File tree

3 files changed

+68
-70
lines changed

3 files changed

+68
-70
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,7 @@ fn assoc_const(
10291029
) -> impl fmt::Display {
10301030
let tcx = cx.tcx();
10311031
fmt::from_fn(move |w| {
1032+
render_attributes_in_code(w, it, &" ".repeat(indent), cx);
10321033
write!(
10331034
w,
10341035
"{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}",
@@ -1136,10 +1137,10 @@ fn assoc_method(
11361137
let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
11371138
header_len += 4;
11381139
let indent_str = " ";
1139-
write!(w, "{}", render_attributes_in_pre(meth, indent_str, cx))?;
1140+
render_attributes_in_code(w, meth, indent_str, cx);
11401141
(4, indent_str, Ending::NoNewline)
11411142
} else {
1142-
render_attributes_in_code(w, meth, cx);
1143+
render_attributes_in_code(w, meth, "", cx);
11431144
(0, "", Ending::Newline)
11441145
};
11451146
write!(
@@ -1309,28 +1310,28 @@ fn render_assoc_item(
13091310
})
13101311
}
13111312

1312-
// When an attribute is rendered inside a `<pre>` tag, it is formatted using
1313-
// a whitespace prefix and newline.
1314-
fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display {
1315-
fmt::from_fn(move |f| {
1316-
for a in it.attributes(cx.tcx(), cx.cache()) {
1317-
writeln!(f, "{prefix}{a}")?;
1318-
}
1319-
Ok(())
1320-
})
1321-
}
1322-
13231313
struct CodeAttribute(String);
13241314

1325-
fn render_code_attribute(code_attr: CodeAttribute, w: &mut impl fmt::Write) {
1326-
write!(w, "<div class=\"code-attribute\">{}</div>", code_attr.0).unwrap();
1315+
fn render_code_attribute(prefix: &str, code_attr: CodeAttribute, w: &mut impl fmt::Write) {
1316+
write!(
1317+
w,
1318+
"<div class=\"code-attribute\">{prefix}{attr}</div>",
1319+
prefix = prefix,
1320+
attr = code_attr.0
1321+
)
1322+
.unwrap();
13271323
}
13281324

13291325
// When an attribute is rendered inside a <code> tag, it is formatted using
13301326
// a div to produce a newline after it.
1331-
fn render_attributes_in_code(w: &mut impl fmt::Write, it: &clean::Item, cx: &Context<'_>) {
1327+
fn render_attributes_in_code(
1328+
w: &mut impl fmt::Write,
1329+
it: &clean::Item,
1330+
prefix: &str,
1331+
cx: &Context<'_>,
1332+
) {
13321333
for attr in it.attributes(cx.tcx(), cx.cache()) {
1333-
render_code_attribute(CodeAttribute(attr), w);
1334+
render_code_attribute(prefix, CodeAttribute(attr), w);
13341335
}
13351336
}
13361337

@@ -1342,7 +1343,7 @@ fn render_repr_attributes_in_code(
13421343
item_type: ItemType,
13431344
) {
13441345
if let Some(repr) = clean::repr_attributes(cx.tcx(), cx.cache(), def_id, item_type) {
1345-
render_code_attribute(CodeAttribute(repr), w);
1346+
render_code_attribute("", CodeAttribute(repr), w);
13461347
}
13471348
}
13481349

src/librustdoc/html/render/print_item.rs

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use super::{
2020
AssocItemLink, AssocItemRender, Context, ImplRenderingParameters, RenderMode,
2121
collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
2222
item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
23-
render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
24-
render_impl, render_repr_attributes_in_code, render_rightside, render_stability_since_raw,
23+
render_assoc_item, render_assoc_items, render_attributes_in_code, render_impl,
24+
render_repr_attributes_in_code, render_rightside, render_stability_since_raw,
2525
render_stability_since_raw_with_extra, write_section_heading,
2626
};
2727
use crate::clean;
@@ -107,13 +107,6 @@ macro_rules! item_template_methods {
107107
}
108108
item_template_methods!($($rest)*);
109109
};
110-
(render_attributes_in_pre $($rest:tt)*) => {
111-
fn render_attributes_in_pre(&self) -> impl fmt::Display {
112-
let (item, cx) = self.item_and_cx();
113-
render_attributes_in_pre(item, "", cx)
114-
}
115-
item_template_methods!($($rest)*);
116-
};
117110
(render_assoc_items $($rest:tt)*) => {
118111
fn render_assoc_items(&self) -> impl fmt::Display {
119112
let (item, cx) = self.item_and_cx();
@@ -457,7 +450,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
457450
write!(
458451
w,
459452
"<dt{id}>\
460-
<code>{vis}{imp}</code>{stab_tags}\
453+
<code>"
454+
)?;
455+
render_attributes_in_code(w, myitem, "", cx);
456+
write!(
457+
w,
458+
"{vis}{imp}</code>{stab_tags}\
461459
</dt>",
462460
vis = visibility_print_with_space(myitem, cx),
463461
imp = import.print(cx)
@@ -625,11 +623,11 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp
625623
let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display();
626624

627625
wrap_item(w, |w| {
626+
render_attributes_in_code(w, it, "", cx);
628627
write!(
629628
w,
630-
"{attrs}{vis}{constness}{asyncness}{safety}{abi}fn \
629+
"{vis}{constness}{asyncness}{safety}{abi}fn \
631630
{name}{generics}{decl}{notable_traits}{where_clause}",
632-
attrs = render_attributes_in_pre(it, "", cx),
633631
vis = visibility,
634632
constness = constness,
635633
asyncness = asyncness,
@@ -666,10 +664,10 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
666664

667665
// Output the trait definition
668666
wrap_item(w, |mut w| {
667+
render_attributes_in_code(&mut w, it, "", cx);
669668
write!(
670669
w,
671-
"{attrs}{vis}{safety}{is_auto}trait {name}{generics}{bounds}",
672-
attrs = render_attributes_in_pre(it, "", cx),
670+
"{vis}{safety}{is_auto}trait {name}{generics}{bounds}",
673671
vis = visibility_print_with_space(it, cx),
674672
safety = t.safety(tcx).print_with_space(),
675673
is_auto = if t.is_auto(tcx) { "auto " } else { "" },
@@ -1240,10 +1238,10 @@ fn item_trait_alias(
12401238
) -> impl fmt::Display {
12411239
fmt::from_fn(|w| {
12421240
wrap_item(w, |w| {
1241+
render_attributes_in_code(w, it, "", cx);
12431242
write!(
12441243
w,
1245-
"{attrs}trait {name}{generics} = {bounds}{where_clause};",
1246-
attrs = render_attributes_in_pre(it, "", cx),
1244+
"trait {name}{generics} = {bounds}{where_clause};",
12471245
name = it.name.unwrap(),
12481246
generics = t.generics.print(cx),
12491247
bounds = print_bounds(&t.bounds, true, cx),
@@ -1268,10 +1266,10 @@ fn item_trait_alias(
12681266
fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display {
12691267
fmt::from_fn(|w| {
12701268
wrap_item(w, |w| {
1269+
render_attributes_in_code(w, it, "", cx);
12711270
write!(
12721271
w,
1273-
"{attrs}{vis}type {name}{generics}{where_clause} = {type_};",
1274-
attrs = render_attributes_in_pre(it, "", cx),
1272+
"{vis}type {name}{generics}{where_clause} = {type_};",
12751273
vis = visibility_print_with_space(it, cx),
12761274
name = it.name.unwrap(),
12771275
generics = t.generics.print(cx),
@@ -1452,7 +1450,14 @@ item_template!(
14521450

14531451
impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
14541452
fn render_union(&self) -> impl Display {
1455-
render_union(self.it, Some(self.generics), self.fields, self.cx)
1453+
render_union(
1454+
self.it,
1455+
Some(self.generics),
1456+
self.fields,
1457+
self.def_id,
1458+
self.is_type_alias,
1459+
self.cx,
1460+
)
14561461
}
14571462

14581463
fn document_field(&self, field: &'a clean::Item) -> impl Display {
@@ -1479,27 +1484,6 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
14791484
_ => None,
14801485
})
14811486
}
1482-
1483-
fn render_attributes_in_pre(&self) -> impl fmt::Display {
1484-
fmt::from_fn(move |f| {
1485-
if self.is_type_alias {
1486-
// For now the only attributes we render for type aliases are `repr` attributes.
1487-
if let Some(repr) = clean::repr_attributes(
1488-
self.cx.tcx(),
1489-
self.cx.cache(),
1490-
self.def_id,
1491-
ItemType::Union,
1492-
) {
1493-
writeln!(f, "{repr}")?;
1494-
};
1495-
} else {
1496-
for a in self.it.attributes(self.cx.tcx(), self.cx.cache()) {
1497-
writeln!(f, "{a}")?;
1498-
}
1499-
}
1500-
Ok(())
1501-
})
1502-
}
15031487
}
15041488

15051489
fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display {
@@ -1563,7 +1547,7 @@ impl<'clean> DisplayEnum<'clean> {
15631547
// For now the only attributes we render for type aliases are `repr` attributes.
15641548
render_repr_attributes_in_code(w, cx, self.def_id, ItemType::Enum);
15651549
} else {
1566-
render_attributes_in_code(w, it, cx);
1550+
render_attributes_in_code(w, it, "", cx);
15671551
}
15681552
write!(
15691553
w,
@@ -1702,7 +1686,7 @@ fn render_enum_fields(
17021686
if v.is_stripped() {
17031687
continue;
17041688
}
1705-
write!(w, "{}", render_attributes_in_pre(v, TAB, cx))?;
1689+
render_attributes_in_code(w, v, TAB, cx);
17061690
w.write_str(TAB)?;
17071691
match v.kind {
17081692
clean::VariantItem(ref var) => match var.kind {
@@ -1882,6 +1866,7 @@ fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt:
18821866
fmt::from_fn(|w| {
18831867
wrap_item(w, |w| {
18841868
// FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
1869+
render_attributes_in_code(w, it, "", cx);
18851870
if !t.macro_rules {
18861871
write!(w, "{}", visibility_print_with_space(it, cx))?;
18871872
}
@@ -1950,7 +1935,7 @@ fn item_constant(
19501935
fmt::from_fn(|w| {
19511936
wrap_item(w, |w| {
19521937
let tcx = cx.tcx();
1953-
render_attributes_in_code(w, it, cx);
1938+
render_attributes_in_code(w, it, "", cx);
19541939

19551940
write!(
19561941
w,
@@ -2018,7 +2003,7 @@ impl<'a> DisplayStruct<'a> {
20182003
// For now the only attributes we render for type aliases are `repr` attributes.
20192004
render_repr_attributes_in_code(w, cx, self.def_id, ItemType::Struct);
20202005
} else {
2021-
render_attributes_in_code(w, it, cx);
2006+
render_attributes_in_code(w, it, "", cx);
20222007
}
20232008
write!(
20242009
w,
@@ -2115,7 +2100,7 @@ fn item_static(
21152100
) -> impl fmt::Display {
21162101
fmt::from_fn(move |w| {
21172102
wrap_item(w, |w| {
2118-
render_attributes_in_code(w, it, cx);
2103+
render_attributes_in_code(w, it, "", cx);
21192104
write!(
21202105
w,
21212106
"{vis}{safe}static {mutability}{name}: {typ}",
@@ -2135,7 +2120,7 @@ fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
21352120
fmt::from_fn(|w| {
21362121
wrap_item(w, |w| {
21372122
w.write_str("extern {\n")?;
2138-
render_attributes_in_code(w, it, cx);
2123+
render_attributes_in_code(w, it, "", cx);
21392124
write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap(),)
21402125
})?;
21412126

@@ -2358,9 +2343,17 @@ fn render_union(
23582343
it: &clean::Item,
23592344
g: Option<&clean::Generics>,
23602345
fields: &[clean::Item],
2346+
def_id: DefId,
2347+
is_type_alias: bool,
23612348
cx: &Context<'_>,
23622349
) -> impl Display {
23632350
fmt::from_fn(move |mut f| {
2351+
if is_type_alias {
2352+
// For now the only attributes we render for type aliases are `repr` attributes.
2353+
render_repr_attributes_in_code(f, cx, def_id, ItemType::Union);
2354+
} else {
2355+
render_attributes_in_code(f, it, "", cx);
2356+
}
23642357
write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
23652358

23662359
let where_displayed = if let Some(generics) = g {
@@ -2390,6 +2383,7 @@ fn render_union(
23902383

23912384
for field in fields {
23922385
if let clean::StructFieldItem(ref ty) = field.kind {
2386+
render_attributes_in_code(&mut f, field, " ", cx);
23932387
writeln!(
23942388
f,
23952389
" {}{}: {},",
@@ -2481,11 +2475,15 @@ fn render_struct_fields(
24812475
if toggle {
24822476
toggle_open(&mut *w, format_args!("{count_fields} fields"));
24832477
}
2478+
if has_visible_fields {
2479+
writeln!(w)?;
2480+
}
24842481
for field in fields {
24852482
if let clean::StructFieldItem(ref ty) = field.kind {
2486-
write!(
2483+
render_attributes_in_code(w, field, &format!("{tab} "), cx);
2484+
writeln!(
24872485
w,
2488-
"\n{tab} {vis}{name}: {ty},",
2486+
"{tab} {vis}{name}: {ty},",
24892487
vis = visibility_print_with_space(field, cx),
24902488
name = field.name.unwrap(),
24912489
ty = ty.print(cx)
@@ -2495,12 +2493,12 @@ fn render_struct_fields(
24952493

24962494
if has_visible_fields {
24972495
if has_stripped_entries {
2498-
write!(
2496+
writeln!(
24992497
w,
2500-
"\n{tab} <span class=\"comment\">/* private fields */</span>"
2498+
"{tab} <span class=\"comment\">/* private fields */</span>"
25012499
)?;
25022500
}
2503-
write!(w, "\n{tab}")?;
2501+
write!(w, "{tab}")?;
25042502
} else if has_stripped_entries {
25052503
write!(w, " <span class=\"comment\">/* private fields */</span> ")?;
25062504
}

src/librustdoc/html/templates/item_union.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<pre class="rust item-decl"><code>
2-
{{ self.render_attributes_in_pre()|safe }}
32
{{ self.render_union()|safe }}
43
</code></pre>
54
{% if !self.is_type_alias %}

0 commit comments

Comments
 (0)