Skip to content

Commit 61b6f65

Browse files
Get repr information through AdtDef for foreign items
1 parent 344dd0e commit 61b6f65

File tree

3 files changed

+72
-21
lines changed

3 files changed

+72
-21
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -849,10 +849,10 @@ fn assoc_method(
849849
let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
850850
header_len += 4;
851851
let indent_str = " ";
852-
write!(w, "{}", render_attributes_in_pre(meth, indent_str));
852+
write!(w, "{}", render_attributes_in_pre(meth, indent_str, tcx));
853853
(4, indent_str, Ending::NoNewline)
854854
} else {
855-
render_attributes_in_code(w, meth);
855+
render_attributes_in_code(w, meth, tcx);
856856
(0, "", Ending::Newline)
857857
};
858858
w.reserve(header_len + "<a href=\"\" class=\"fn\">{".len() + "</a>".len());
@@ -1024,8 +1024,12 @@ fn render_assoc_item(
10241024
const ALLOWED_ATTRIBUTES: &[Symbol] =
10251025
&[sym::export_name, sym::link_section, sym::no_mangle, sym::repr, sym::non_exhaustive];
10261026

1027-
fn attributes(it: &clean::Item) -> Vec<String> {
1028-
it.attrs
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
10291033
.other_attrs
10301034
.iter()
10311035
.filter_map(|attr| {
@@ -1040,17 +1044,62 @@ fn attributes(it: &clean::Item) -> Vec<String> {
10401044
None
10411045
}
10421046
})
1043-
.collect()
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
10441092
}
10451093

10461094
// When an attribute is rendered inside a `<pre>` tag, it is formatted using
10471095
// a whitespace prefix and newline.
1048-
fn render_attributes_in_pre<'a>(
1096+
fn render_attributes_in_pre<'a, 'b: 'a>(
10491097
it: &'a clean::Item,
10501098
prefix: &'a str,
1051-
) -> impl fmt::Display + Captures<'a> {
1099+
tcx: TyCtxt<'b>,
1100+
) -> impl fmt::Display + Captures<'a> + Captures<'b> {
10521101
crate::html::format::display_fn(move |f| {
1053-
for a in attributes(it) {
1102+
for a in attributes(it, tcx) {
10541103
writeln!(f, "{}{}", prefix, a)?;
10551104
}
10561105
Ok(())
@@ -1059,8 +1108,8 @@ fn render_attributes_in_pre<'a>(
10591108

10601109
// When an attribute is rendered inside a <code> tag, it is formatted using
10611110
// a div to produce a newline after it.
1062-
fn render_attributes_in_code(w: &mut Buffer, it: &clean::Item) {
1063-
for a in attributes(it) {
1111+
fn render_attributes_in_code(w: &mut Buffer, it: &clean::Item, tcx: TyCtxt<'_>) {
1112+
for a in attributes(it, tcx) {
10641113
write!(w, "<div class=\"code-attribute\">{}</div>", a);
10651114
}
10661115
}

src/librustdoc/html/render/print_item.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
548548
w,
549549
"{attrs}{vis}{constness}{asyncness}{unsafety}{abi}fn \
550550
{name}{generics}{decl}{notable_traits}{where_clause}",
551-
attrs = render_attributes_in_pre(it, ""),
551+
attrs = render_attributes_in_pre(it, "", tcx),
552552
vis = visibility,
553553
constness = constness,
554554
asyncness = asyncness,
@@ -589,7 +589,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
589589
it.name.unwrap(),
590590
t.generics.print(cx),
591591
bounds,
592-
attrs = render_attributes_in_pre(it, ""),
592+
attrs = render_attributes_in_pre(it, "", tcx),
593593
);
594594

595595
if !t.generics.where_predicates.is_empty() {
@@ -1063,7 +1063,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &
10631063
t.generics.print(cx),
10641064
print_where_clause(&t.generics, cx, 0, Ending::Newline),
10651065
bounds(&t.bounds, true, cx),
1066-
attrs = render_attributes_in_pre(it, ""),
1066+
attrs = render_attributes_in_pre(it, "", cx.tcx()),
10671067
);
10681068
});
10691069

@@ -1085,7 +1085,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &cl
10851085
t.generics.print(cx),
10861086
where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
10871087
bounds = bounds(&t.bounds, false, cx),
1088-
attrs = render_attributes_in_pre(it, ""),
1088+
attrs = render_attributes_in_pre(it, "", cx.tcx()),
10891089
);
10901090
});
10911091

@@ -1109,7 +1109,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
11091109
t.generics.print(cx),
11101110
where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
11111111
type_ = t.type_.print(cx),
1112-
attrs = render_attributes_in_pre(it, ""),
1112+
attrs = render_attributes_in_pre(it, "", cx.tcx()),
11131113
);
11141114
});
11151115
}
@@ -1168,7 +1168,8 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
11681168
&'b self,
11691169
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
11701170
display_fn(move |f| {
1171-
let v = render_attributes_in_pre(self.it, "");
1171+
let tcx = self.cx.borrow().tcx();
1172+
let v = render_attributes_in_pre(self.it, "", tcx);
11721173
write!(f, "{v}")
11731174
})
11741175
}
@@ -1250,7 +1251,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
12501251
visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
12511252
it.name.unwrap(),
12521253
e.generics.print(cx),
1253-
attrs = render_attributes_in_pre(it, ""),
1254+
attrs = render_attributes_in_pre(it, "", tcx),
12541255
);
12551256
if !print_where_clause_and_check(w, &e.generics, cx) {
12561257
// If there wasn't a `where` clause, we add a whitespace.
@@ -1445,7 +1446,7 @@ fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
14451446
fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) {
14461447
wrap_item(w, |w| {
14471448
let tcx = cx.tcx();
1448-
render_attributes_in_code(w, it);
1449+
render_attributes_in_code(w, it, tcx);
14491450

14501451
write!(
14511452
w,
@@ -1492,7 +1493,7 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
14921493

14931494
fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Struct) {
14941495
wrap_item(w, |w| {
1495-
render_attributes_in_code(w, it);
1496+
render_attributes_in_code(w, it, cx.tcx());
14961497
render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx);
14971498
});
14981499

@@ -1542,7 +1543,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
15421543

15431544
fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Static) {
15441545
wrap_item(w, |w| {
1545-
render_attributes_in_code(w, it);
1546+
render_attributes_in_code(w, it, cx.tcx());
15461547
write!(
15471548
w,
15481549
"{vis}static {mutability}{name}: {typ}",
@@ -1558,7 +1559,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
15581559
fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
15591560
wrap_item(w, |w| {
15601561
w.write_str("extern {\n");
1561-
render_attributes_in_code(w, it);
1562+
render_attributes_in_code(w, it, cx.tcx());
15621563
write!(
15631564
w,
15641565
" {}type {};\n}}",

src/librustdoc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern crate tracing;
3333
// Dependencies listed in Cargo.toml do not need `extern crate`.
3434

3535
extern crate pulldown_cmark;
36+
extern crate rustc_abi;
3637
extern crate rustc_ast;
3738
extern crate rustc_ast_pretty;
3839
extern crate rustc_attr;

0 commit comments

Comments
 (0)