Skip to content

Commit 00e1183

Browse files
committed
[squash-before-merge] better #[repr]
1 parent 157ec24 commit 00e1183

File tree

2 files changed

+68
-17
lines changed

2 files changed

+68
-17
lines changed

src/librustdoc/json/conversions.rs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ fn maybe_from_hir_attr(
913913
{
914914
Attribute::DocHidden
915915
} else {
916-
Attribute::Other(rustc_hir_pretty::attribute_to_string(&tcx, attr))
916+
other_attr(tcx, attr)
917917
});
918918
}
919919
};
@@ -925,22 +925,59 @@ fn maybe_from_hir_attr(
925925
AK::MustUse { reason, span: _ } => {
926926
Attribute::MustUse { reason: reason.map(|s| s.to_string()) }
927927
}
928-
AK::Repr { .. } => Attribute::Repr(repr(item_id.as_def_id().expect("reason"), tcx)),
928+
AK::Repr { .. } => repr_attr(
929+
tcx,
930+
item_id.as_def_id().expect("all items that could have #[repr] have a DefId"),
931+
),
929932
AK::NoMangle(_) => Attribute::NoMangle,
930933

931-
_ => Attribute::Other(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
934+
_ => other_attr(tcx, attr),
932935
})
933936
}
934937

935-
fn repr(def_id: DefId, tcx: TyCtxt<'_>) -> AttributeRepr {
938+
fn other_attr(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Attribute {
939+
let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr);
940+
assert_eq!(s.pop(), Some('\n'));
941+
Attribute::Other(s)
942+
}
943+
944+
fn repr_attr(tcx: TyCtxt<'_>, def_id: DefId) -> Attribute {
936945
let repr = tcx.adt_def(def_id).repr();
937946

938947
// FIXME: This is wildly insufficient
939-
if repr.c() {
940-
AttributeRepr::C
948+
let kind = if repr.c() {
949+
ReprKind::C
941950
} else if repr.transparent() {
942-
AttributeRepr::Transparent
951+
ReprKind::Transparent
952+
} else if repr.simd() {
953+
ReprKind::Simd
943954
} else {
944-
AttributeRepr::Rust
945-
}
955+
ReprKind::Rust
956+
};
957+
958+
let align = repr.align.map(|a| a.bytes());
959+
let packed = repr.pack.map(|p| p.bytes());
960+
let int = repr.int.map(format_integer_type);
961+
962+
Attribute::Repr(AttributeRepr { kind, align, packed, int })
963+
}
964+
965+
fn format_integer_type(it: rustc_abi::IntegerType) -> String {
966+
use rustc_abi::Integer::*;
967+
use rustc_abi::IntegerType::*;
968+
match it {
969+
Pointer(true) => "isize",
970+
Pointer(false) => "usize",
971+
Fixed(I8, true) => "i8",
972+
Fixed(I8, false) => "u8",
973+
Fixed(I16, true) => "i16",
974+
Fixed(I16, false) => "u16",
975+
Fixed(I32, true) => "i32",
976+
Fixed(I32, false) => "u32",
977+
Fixed(I64, true) => "i64",
978+
Fixed(I64, false) => "u64",
979+
Fixed(I128, true) => "i128",
980+
Fixed(I128, false) => "u128",
981+
}
982+
.to_owned()
946983
}

src/rustdoc-json-types/lib.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
3737
// will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line
3838
// are deliberately not in a doc comment, because they need not be in public docs.)
3939
//
40-
// Latest feature: Structed Attributes
40+
// Latest feature: Structured Attributes
4141
pub const FORMAT_VERSION: u32 = 54;
4242

4343
/// The root of the emitted JSON blob.
@@ -202,14 +202,15 @@ pub struct Item {
202202
pub inner: ItemEnum,
203203
}
204204

205-
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
206205
/// An attribute, eg `#[repr(C)]`
207206
///
208207
/// This doesn't include:
209208
/// - `#[doc = "Doc Comment"]` or `/// Doc comment`. These are in [`Item::docs`] instead.
210-
/// - `#[depricate]`. These are in [`Item::deprecation`] instead.
209+
/// - `#[deprecated]`. These are in [`Item::deprecation`] instead.
210+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
211+
#[serde(rename_all = "snake_case")]
211212
pub enum Attribute {
212-
/// `#[non_exaustive]`
213+
/// `#[non_exhaustive]`
213214
NonExhaustive,
214215

215216
/// `#[must_use]`
@@ -233,16 +234,29 @@ pub enum Attribute {
233234
///
234235
/// Things here are explicitly *not* covered by the [`FORMAT_VERSION`]
235236
/// constant, and may change without bumping the format version. If you rely
236-
/// on an attibute here, please open an issue about adding a new variant for
237+
/// on an attribute here, please open an issue about adding a new variant for
237238
/// that attr.
238239
Other(String),
239240
}
240241

241242
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
242-
pub enum AttributeRepr {
243+
pub struct AttributeRepr {
244+
pub kind: ReprKind,
245+
246+
/// Alignment, in bytes.
247+
pub align: Option<u64>,
248+
pub packed: Option<u64>,
249+
250+
pub int: Option<String>,
251+
}
252+
253+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
254+
#[serde(rename_all = "snake_case")]
255+
pub enum ReprKind {
256+
Rust,
243257
C,
244258
Transparent,
245-
Rust,
259+
Simd,
246260
}
247261

248262
/// A range of source code.
@@ -1386,7 +1400,7 @@ pub struct Static {
13861400

13871401
/// Is the static `unsafe`?
13881402
///
1389-
/// This is only true if it's in an `extern` block, and not explicity marked
1403+
/// This is only true if it's in an `extern` block, and not explicitly marked
13901404
/// as `safe`.
13911405
///
13921406
/// ```rust

0 commit comments

Comments
 (0)