Skip to content

Commit b778688

Browse files
Unify attributes retrieval for JSON and HTML rendering
1 parent 2693e20 commit b778688

File tree

3 files changed

+76
-79
lines changed

3 files changed

+76
-79
lines changed

src/librustdoc/clean/types.rs

+73
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use arrayvec::ArrayVec;
1111
use thin_vec::ThinVec;
1212

1313
use rustc_ast as ast;
14+
use rustc_ast_pretty::pprust;
1415
use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
1516
use rustc_const_eval::const_eval::is_unstable_const_fn;
1617
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -711,6 +712,78 @@ impl Item {
711712
};
712713
Some(tcx.visibility(def_id))
713714
}
715+
716+
pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, keep_as_is: bool) -> Vec<String> {
717+
const ALLOWED_ATTRIBUTES: &[Symbol] =
718+
&[sym::export_name, sym::link_section, sym::no_mangle, sym::repr, sym::non_exhaustive];
719+
720+
use rustc_abi::IntegerType;
721+
use rustc_middle::ty::ReprFlags;
722+
723+
let mut attrs: Vec<String> = self
724+
.attrs
725+
.other_attrs
726+
.iter()
727+
.filter_map(|attr| {
728+
if keep_as_is {
729+
Some(pprust::attribute_to_string(attr))
730+
} else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
731+
Some(
732+
pprust::attribute_to_string(attr)
733+
.replace("\\\n", "")
734+
.replace('\n', "")
735+
.replace(" ", " "),
736+
)
737+
} else {
738+
None
739+
}
740+
})
741+
.collect();
742+
if let Some(def_id) = self.item_id.as_def_id() &&
743+
!def_id.is_local() &&
744+
// This check is needed because `adt_def` will panic if not a compatible type otherwise...
745+
matches!(self.type_(), ItemType::Struct | ItemType::Enum | ItemType::Union)
746+
{
747+
let repr = tcx.adt_def(def_id).repr();
748+
let mut out = Vec::new();
749+
if repr.flags.contains(ReprFlags::IS_C) {
750+
out.push("C");
751+
}
752+
if repr.flags.contains(ReprFlags::IS_TRANSPARENT) {
753+
out.push("transparent");
754+
}
755+
if repr.flags.contains(ReprFlags::IS_SIMD) {
756+
out.push("simd");
757+
}
758+
let pack_s;
759+
if let Some(pack) = repr.pack {
760+
pack_s = format!("packed({})", pack.bytes());
761+
out.push(&pack_s);
762+
}
763+
let align_s;
764+
if let Some(align) = repr.align {
765+
align_s = format!("align({})", align.bytes());
766+
out.push(&align_s);
767+
}
768+
let int_s;
769+
if let Some(int) = repr.int {
770+
int_s = match int {
771+
IntegerType::Pointer(is_signed) => {
772+
format!("{}size", if is_signed { 'i' } else { 'u' })
773+
}
774+
IntegerType::Fixed(size, is_signed) => {
775+
format!("{}{}", if is_signed { 'i' } else { 'u' }, size.size().bytes() * 8)
776+
}
777+
};
778+
out.push(&int_s);
779+
}
780+
if out.is_empty() {
781+
return Vec::new();
782+
}
783+
attrs.push(format!("#[repr({})]", out.join(", ")));
784+
}
785+
attrs
786+
}
714787
}
715788

716789
#[derive(Clone, Debug)]

src/librustdoc/html/render/mod.rs

+2-73
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ use std::str;
4848
use std::string::ToString;
4949

5050
use askama::Template;
51-
use rustc_ast_pretty::pprust;
5251
use rustc_attr::{ConstStability, Deprecation, StabilityLevel};
5352
use rustc_data_structures::captures::Captures;
5453
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -1021,76 +1020,6 @@ fn render_assoc_item(
10211020
}
10221021
}
10231022

1024-
const ALLOWED_ATTRIBUTES: &[Symbol] =
1025-
&[sym::export_name, sym::link_section, sym::no_mangle, sym::repr, sym::non_exhaustive];
1026-
1027-
fn attributes(it: &clean::Item, tcx: TyCtxt<'_>) -> Vec<String> {
1028-
use rustc_abi::IntegerType;
1029-
use rustc_middle::ty::ReprFlags;
1030-
1031-
let mut attrs: Vec<String> = it
1032-
.attrs
1033-
.other_attrs
1034-
.iter()
1035-
.filter_map(|attr| {
1036-
if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
1037-
Some(
1038-
pprust::attribute_to_string(attr)
1039-
.replace("\\\n", "")
1040-
.replace('\n', "")
1041-
.replace(" ", " "),
1042-
)
1043-
} else {
1044-
None
1045-
}
1046-
})
1047-
.collect();
1048-
if let Some(def_id) = it.item_id.as_def_id() &&
1049-
!def_id.is_local() &&
1050-
// This check is needed because `adt_def` will panic if not a compatible type otherwise...
1051-
matches!(it.type_(), ItemType::Struct | ItemType::Enum | ItemType::Union)
1052-
{
1053-
let repr = tcx.adt_def(def_id).repr();
1054-
let mut out = Vec::new();
1055-
if repr.flags.contains(ReprFlags::IS_C) {
1056-
out.push("C");
1057-
}
1058-
if repr.flags.contains(ReprFlags::IS_TRANSPARENT) {
1059-
out.push("transparent");
1060-
}
1061-
if repr.flags.contains(ReprFlags::IS_SIMD) {
1062-
out.push("simd");
1063-
}
1064-
let pack_s;
1065-
if let Some(pack) = repr.pack {
1066-
pack_s = format!("packed({})", pack.bytes());
1067-
out.push(&pack_s);
1068-
}
1069-
let align_s;
1070-
if let Some(align) = repr.align {
1071-
align_s = format!("align({})", align.bytes());
1072-
out.push(&align_s);
1073-
}
1074-
let int_s;
1075-
if let Some(int) = repr.int {
1076-
int_s = match int {
1077-
IntegerType::Pointer(is_signed) => {
1078-
format!("{}size", if is_signed { 'i' } else { 'u' })
1079-
}
1080-
IntegerType::Fixed(size, is_signed) => {
1081-
format!("{}{}", if is_signed { 'i' } else { 'u' }, size.size().bytes() * 8)
1082-
}
1083-
};
1084-
out.push(&int_s);
1085-
}
1086-
if out.is_empty() {
1087-
return Vec::new();
1088-
}
1089-
attrs.push(format!("#[repr({})]", out.join(", ")));
1090-
}
1091-
attrs
1092-
}
1093-
10941023
// When an attribute is rendered inside a `<pre>` tag, it is formatted using
10951024
// a whitespace prefix and newline.
10961025
fn render_attributes_in_pre<'a, 'b: 'a>(
@@ -1099,7 +1028,7 @@ fn render_attributes_in_pre<'a, 'b: 'a>(
10991028
tcx: TyCtxt<'b>,
11001029
) -> impl fmt::Display + Captures<'a> + Captures<'b> {
11011030
crate::html::format::display_fn(move |f| {
1102-
for a in attributes(it, tcx) {
1031+
for a in it.attributes(tcx, false) {
11031032
writeln!(f, "{}{}", prefix, a)?;
11041033
}
11051034
Ok(())
@@ -1109,7 +1038,7 @@ fn render_attributes_in_pre<'a, 'b: 'a>(
11091038
// When an attribute is rendered inside a <code> tag, it is formatted using
11101039
// a div to produce a newline after it.
11111040
fn render_attributes_in_code(w: &mut Buffer, it: &clean::Item, tcx: TyCtxt<'_>) {
1112-
for a in attributes(it, tcx) {
1041+
for a in it.attributes(tcx, false) {
11131042
write!(w, "<div class=\"code-attribute\">{}</div>", a);
11141043
}
11151044
}

src/librustdoc/json/conversions.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ impl JsonRenderer<'_> {
4141
})
4242
.collect();
4343
let docs = item.attrs.collapsed_doc_value();
44-
let attrs = item
45-
.attrs
46-
.other_attrs
47-
.iter()
48-
.map(rustc_ast_pretty::pprust::attribute_to_string)
49-
.collect();
44+
let attrs = item.attributes(self.tcx, true);
5045
let span = item.span(self.tcx);
5146
let visibility = item.visibility(self.tcx);
5247
let clean::Item { name, item_id, .. } = item;

0 commit comments

Comments
 (0)