Skip to content

Commit 4194745

Browse files
Split Item::attributes method into three
1 parent 560aec1 commit 4194745

File tree

3 files changed

+81
-70
lines changed

3 files changed

+81
-70
lines changed

src/librustdoc/clean/types.rs

Lines changed: 78 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -764,14 +764,11 @@ impl Item {
764764
Some(tcx.visibility(def_id))
765765
}
766766

767-
pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, cache: &Cache, is_json: bool) -> Vec<String> {
767+
pub(crate) fn attributes_witout_repr(&self, tcx: TyCtxt<'_>, is_json: bool) -> Vec<String> {
768768
const ALLOWED_ATTRIBUTES: &[Symbol] =
769769
&[sym::export_name, sym::link_section, sym::no_mangle, sym::non_exhaustive];
770770

771-
use rustc_abi::IntegerType;
772-
773-
let mut attrs: Vec<String> = self
774-
.attrs
771+
self.attrs
775772
.other_attrs
776773
.iter()
777774
.filter_map(|attr| {
@@ -799,74 +796,88 @@ impl Item {
799796
None
800797
}
801798
})
802-
.collect();
799+
.collect()
800+
}
803801

804-
// Add #[repr(...)]
805-
if let Some(def_id) = self.def_id()
806-
&& let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_()
807-
{
808-
let adt = tcx.adt_def(def_id);
809-
let repr = adt.repr();
810-
let mut out = Vec::new();
811-
if repr.c() {
812-
out.push("C");
813-
}
814-
if repr.transparent() {
815-
// Render `repr(transparent)` iff the non-1-ZST field is public or at least one
816-
// field is public in case all fields are 1-ZST fields.
817-
let render_transparent = is_json
818-
|| cache.document_private
819-
|| adt
820-
.all_fields()
821-
.find(|field| {
822-
let ty =
823-
field.ty(tcx, ty::GenericArgs::identity_for_item(tcx, field.did));
824-
tcx.layout_of(
825-
ty::TypingEnv::post_analysis(tcx, field.did).as_query_input(ty),
826-
)
827-
.is_ok_and(|layout| !layout.is_1zst())
828-
})
829-
.map_or_else(
830-
|| adt.all_fields().any(|field| field.vis.is_public()),
831-
|field| field.vis.is_public(),
832-
);
802+
pub(crate) fn attributes_and_repr(
803+
&self,
804+
tcx: TyCtxt<'_>,
805+
cache: &Cache,
806+
is_json: bool,
807+
) -> Vec<String> {
808+
let mut attrs = self.attributes_witout_repr(tcx, is_json);
833809

834-
if render_transparent {
835-
out.push("transparent");
836-
}
837-
}
838-
if repr.simd() {
839-
out.push("simd");
840-
}
841-
let pack_s;
842-
if let Some(pack) = repr.pack {
843-
pack_s = format!("packed({})", pack.bytes());
844-
out.push(&pack_s);
845-
}
846-
let align_s;
847-
if let Some(align) = repr.align {
848-
align_s = format!("align({})", align.bytes());
849-
out.push(&align_s);
850-
}
851-
let int_s;
852-
if let Some(int) = repr.int {
853-
int_s = match int {
854-
IntegerType::Pointer(is_signed) => {
855-
format!("{}size", if is_signed { 'i' } else { 'u' })
856-
}
857-
IntegerType::Fixed(size, is_signed) => {
858-
format!("{}{}", if is_signed { 'i' } else { 'u' }, size.size().bytes() * 8)
859-
}
860-
};
861-
out.push(&int_s);
862-
}
863-
if !out.is_empty() {
864-
attrs.push(format!("#[repr({})]", out.join(", ")));
865-
}
810+
if let Some(repr_attr) = self.repr(tcx, cache) {
811+
attrs.push(repr_attr);
866812
}
867813
attrs
868814
}
869815

816+
/// Returns a `#[repr(...)]` representation.
817+
pub(crate) fn repr(&self, tcx: TyCtxt<'_>, cache: &Cache, is_json: bool) -> Option<String> {
818+
use rustc_abi::IntegerType;
819+
820+
let def_id = self.def_id()?;
821+
if !matches!(self.type_(), ItemType::Struct | ItemType::Enum | ItemType::Union) {
822+
return None;
823+
}
824+
let adt = tcx.adt_def(def_id);
825+
let repr = adt.repr();
826+
let mut out = Vec::new();
827+
if repr.c() {
828+
out.push("C");
829+
}
830+
if repr.transparent() {
831+
// Render `repr(transparent)` iff the non-1-ZST field is public or at least one
832+
// field is public in case all fields are 1-ZST fields.
833+
let render_transparent = is_json
834+
|| cache.document_private
835+
|| adt
836+
.all_fields()
837+
.find(|field| {
838+
let ty = field.ty(tcx, ty::GenericArgs::identity_for_item(tcx, field.did));
839+
tcx.layout_of(
840+
ty::TypingEnv::post_analysis(tcx, field.did).as_query_input(ty),
841+
)
842+
.is_ok_and(|layout| !layout.is_1zst())
843+
})
844+
.map_or_else(
845+
|| adt.all_fields().any(|field| field.vis.is_public()),
846+
|field| field.vis.is_public(),
847+
);
848+
849+
if render_transparent {
850+
out.push("transparent");
851+
}
852+
}
853+
if repr.simd() {
854+
out.push("simd");
855+
}
856+
let pack_s;
857+
if let Some(pack) = repr.pack {
858+
pack_s = format!("packed({})", pack.bytes());
859+
out.push(&pack_s);
860+
}
861+
let align_s;
862+
if let Some(align) = repr.align {
863+
align_s = format!("align({})", align.bytes());
864+
out.push(&align_s);
865+
}
866+
let int_s;
867+
if let Some(int) = repr.int {
868+
int_s = match int {
869+
IntegerType::Pointer(is_signed) => {
870+
format!("{}size", if is_signed { 'i' } else { 'u' })
871+
}
872+
IntegerType::Fixed(size, is_signed) => {
873+
format!("{}{}", if is_signed { 'i' } else { 'u' }, size.size().bytes() * 8)
874+
}
875+
};
876+
out.push(&int_s);
877+
}
878+
if !out.is_empty() { Some(format!("#[repr({})]", out.join(", "))) } else { None }
879+
}
880+
870881
pub fn is_doc_hidden(&self) -> bool {
871882
self.attrs.is_doc_hidden()
872883
}

src/librustdoc/html/render/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ fn render_assoc_item(
11941194
// a whitespace prefix and newline.
11951195
fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display {
11961196
fmt::from_fn(move |f| {
1197-
for a in it.attributes(cx.tcx(), cx.cache(), false) {
1197+
for a in it.attributes_and_repr(cx.tcx(), cx.cache(), false) {
11981198
writeln!(f, "{prefix}{a}")?;
11991199
}
12001200
Ok(())
@@ -1204,7 +1204,7 @@ fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) ->
12041204
// When an attribute is rendered inside a <code> tag, it is formatted using
12051205
// a div to produce a newline after it.
12061206
fn render_attributes_in_code(w: &mut impl fmt::Write, it: &clean::Item, cx: &Context<'_>) {
1207-
for attr in it.attributes(cx.tcx(), cx.cache(), false) {
1207+
for attr in it.attributes_and_repr(cx.tcx(), cx.cache(), false) {
12081208
write!(w, "<div class=\"code-attribute\">{attr}</div>").unwrap();
12091209
}
12101210
}

src/librustdoc/json/conversions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl JsonRenderer<'_> {
4040
})
4141
.collect();
4242
let docs = item.opt_doc_value();
43-
let attrs = item.attributes(self.tcx, self.cache(), true);
43+
let attrs = item.attributes_and_repr(self.tcx, self.cache(), true);
4444
let span = item.span(self.tcx);
4545
let visibility = item.visibility(self.tcx);
4646
let clean::ItemInner { name, item_id, .. } = *item.inner;

0 commit comments

Comments
 (0)