Skip to content

Commit 91180a5

Browse files
Split Item::attributes method into three
1 parent f324b8f commit 91180a5

File tree

3 files changed

+80
-69
lines changed

3 files changed

+80
-69
lines changed

src/librustdoc/clean/types.rs

Lines changed: 77 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -762,14 +762,11 @@ impl Item {
762762
Some(tcx.visibility(def_id))
763763
}
764764

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

769-
use rustc_abi::IntegerType;
770-
771-
let mut attrs: Vec<String> = self
772-
.attrs
769+
self.attrs
773770
.other_attrs
774771
.iter()
775772
.filter_map(|attr| {
@@ -806,73 +803,87 @@ impl Item {
806803
None
807804
}
808805
})
809-
.collect();
806+
.collect()
807+
}
810808

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

840-
if render_transparent {
841-
out.push("transparent");
842-
}
843-
}
844-
if repr.simd() {
845-
out.push("simd");
846-
}
847-
let pack_s;
848-
if let Some(pack) = repr.pack {
849-
pack_s = format!("packed({})", pack.bytes());
850-
out.push(&pack_s);
851-
}
852-
let align_s;
853-
if let Some(align) = repr.align {
854-
align_s = format!("align({})", align.bytes());
855-
out.push(&align_s);
856-
}
857-
let int_s;
858-
if let Some(int) = repr.int {
859-
int_s = match int {
860-
IntegerType::Pointer(is_signed) => {
861-
format!("{}size", if is_signed { 'i' } else { 'u' })
862-
}
863-
IntegerType::Fixed(size, is_signed) => {
864-
format!("{}{}", if is_signed { 'i' } else { 'u' }, size.size().bytes() * 8)
865-
}
866-
};
867-
out.push(&int_s);
868-
}
869-
if !out.is_empty() {
870-
attrs.push(format!("#[repr({})]", out.join(", ")));
871-
}
817+
if let Some(repr_attr) = self.repr(tcx, cache) {
818+
attrs.push(repr_attr);
872819
}
873820
attrs
874821
}
875822

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

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)