Skip to content

Commit 743870f

Browse files
committed
rustdoc: Use own logic to print #[repr(..)] attributes in JSON output.
1 parent 78948ac commit 743870f

File tree

8 files changed

+62
-39
lines changed

8 files changed

+62
-39
lines changed

src/librustdoc/clean/types.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -768,12 +768,22 @@ impl Item {
768768
.iter()
769769
.filter_map(|attr| {
770770
if is_json {
771-
if matches!(attr, hir::Attribute::Parsed(AttributeKind::Deprecation { .. })) {
772-
// rustdoc-json stores this in `Item::deprecation`, so we
773-
// don't want it it `Item::attrs`.
774-
None
775-
} else {
776-
Some(rustc_hir_pretty::attribute_to_string(&tcx, attr))
771+
match attr {
772+
hir::Attribute::Parsed(AttributeKind::Deprecation { .. }) => {
773+
// rustdoc-json stores this in `Item::deprecation`, so we
774+
// don't want it it `Item::attrs`.
775+
None
776+
}
777+
rustc_hir::Attribute::Parsed(rustc_attr_parsing::AttributeKind::Repr(
778+
..,
779+
)) => {
780+
// We have separate pretty-printing logic for `#[repr(..)]` attributes.
781+
// For example, there are circumstances where `#[repr(transparent)]`
782+
// is applied but should not be publicly shown in rustdoc
783+
// because it isn't public API.
784+
None
785+
}
786+
_ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
777787
}
778788
} else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
779789
Some(
@@ -789,8 +799,7 @@ impl Item {
789799
.collect();
790800

791801
// Add #[repr(...)]
792-
if !is_json
793-
&& let Some(def_id) = self.def_id()
802+
if let Some(def_id) = self.def_id()
794803
&& let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_()
795804
{
796805
let adt = tcx.adt_def(def_id);

src/rustdoc-json-types/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
3030
/// This integer is incremented with every breaking change to the API,
3131
/// and is returned along with the JSON blob as [`Crate::format_version`].
3232
/// Consuming code should assert that this value matches the format version(s) that it supports.
33-
pub const FORMAT_VERSION: u32 = 42;
33+
pub const FORMAT_VERSION: u32 = 43;
3434

3535
/// The root of the emitted JSON blob.
3636
///

tests/rustdoc-json/attrs/repr_align.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![no_std]
22

3-
//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]'
3+
//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[repr(align(4))]"]'
44
#[repr(align(4))]
55
pub struct Aligned {
66
a: i8,

tests/rustdoc-json/attrs/repr_c.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#![no_std]
22

3-
//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]'
3+
//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[repr(C)]"]'
44
#[repr(C)]
55
pub struct ReprCStruct(pub i64);
66

7-
//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]'
7+
//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[repr(C)]"]'
88
#[repr(C)]
99
pub enum ReprCEnum {
1010
First,
1111
}
1212

13-
//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]'
13+
//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[repr(C)]"]'
1414
#[repr(C)]
1515
pub union ReprCUnion {
1616
pub left: i64,

tests/rustdoc-json/attrs/repr_combination.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,78 @@
11
#![no_std]
22

33
// Combinations of `#[repr(..)]` attributes.
4+
// Rustdoc JSON emits normalized output, regardless of the original source.
45

5-
//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]'
6+
//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[repr(C, i8)]"]'
67
#[repr(C, i8)]
78
pub enum ReprCI8 {
89
First,
910
}
1011

11-
//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]'
12+
//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[repr(C, i16)]"]'
1213
#[repr(C)]
1314
#[repr(i16)]
1415
pub enum SeparateReprCI16 {
1516
First,
1617
}
1718

18-
//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]'
19+
//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[repr(C, usize)]"]'
1920
#[repr(usize, C)]
2021
pub enum ReversedReprCUsize {
2122
First,
2223
}
2324

24-
//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]'
25+
//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[repr(C, packed(1))]"]'
2526
#[repr(C, packed)]
2627
pub struct ReprCPacked {
2728
a: i8,
2829
b: i64,
2930
}
3031

31-
//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]'
32+
//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
3233
#[repr(C)]
3334
#[repr(packed(2))]
3435
pub struct SeparateReprCPacked {
3536
a: i8,
3637
b: i64,
3738
}
3839

39-
//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]'
40+
//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
4041
#[repr(packed(2), C)]
4142
pub struct ReversedReprCPacked {
4243
a: i8,
4344
b: i64,
4445
}
4546

46-
//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]'
47+
//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[repr(C, align(16))]"]'
4748
#[repr(C, align(16))]
4849
pub struct ReprCAlign {
4950
a: i8,
5051
b: i64,
5152
}
5253

53-
//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]'
54+
//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
5455
#[repr(C)]
5556
#[repr(align(2))]
5657
pub struct SeparateReprCAlign {
5758
a: i8,
5859
b: i64,
5960
}
6061

61-
//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]'
62+
//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
6263
#[repr(align(2), C)]
6364
pub struct ReversedReprCAlign {
6465
a: i8,
6566
b: i64,
6667
}
6768

68-
//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]'
69+
//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
6970
#[repr(C, align(16), isize)]
7071
pub enum AlignedExplicitRepr {
7172
First,
7273
}
7374

74-
//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]'
75+
//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
7576
#[repr(isize, C, align(16))]
7677
pub enum ReorderedAlignedExplicitRepr {
7778
First,

tests/rustdoc-json/attrs/repr_int_enum.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#![no_std]
22

3-
//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]'
3+
//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[repr(i8)]"]'
44
#[repr(i8)]
55
pub enum I8 {
66
First,
77
}
88

9-
//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
9+
//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[repr(i32)]"]'
1010
#[repr(i32)]
1111
pub enum I32 {
1212
First,
1313
}
1414

15-
//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]'
15+
//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[repr(usize)]"]'
1616
#[repr(usize)]
1717
pub enum Usize {
1818
First,

tests/rustdoc-json/attrs/repr_packed.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#![no_std]
22

33
// Note the normalization:
4-
// `#[repr(packed)]` in has the implict "1" in rustdoc JSON.
5-
6-
//@ is "$.index[*][?(@.name=='Packed')].attrs" '["#[attr = Repr([ReprPacked(Align(1 bytes))])]\n"]'
4+
// `#[repr(packed)]` in source becomes `#[repr(packed(1))]` in rustdoc JSON.
5+
//
6+
//@ is "$.index[*][?(@.name=='Packed')].attrs" '["#[repr(packed(1))]"]'
77
#[repr(packed)]
88
pub struct Packed {
99
a: i8,
1010
b: i64,
1111
}
1212

13-
//@ is "$.index[*][?(@.name=='PackedAligned')].attrs" '["#[attr = Repr([ReprPacked(Align(4 bytes))])]\n"]'
13+
//@ is "$.index[*][?(@.name=='PackedAligned')].attrs" '["#[repr(packed(4))]"]'
1414
#[repr(packed(4))]
1515
pub struct PackedAligned {
1616
a: i8,
+21-8
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
#![no_std]
22

3-
// Rustdoc JSON currently includes `#[repr(transparent)]`
4-
// even if the transparency is not part of the public API
5-
//
6-
// https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
3+
// Rustdoc JSON *only* includes `#[repr(transparent)]`
4+
// if the transparency is public API:
5+
// - if a non-1-ZST field exists, it has to be public
6+
// - otherwise, all fields are 1-ZST and at least one of them is public
77

8-
//@ is "$.index[*][?(@.name=='Transparent')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
8+
// Here, the non-1-ZST field is public.
9+
// We expect `#[repr(transparent)]` in the attributes.
10+
//
11+
//@ is "$.index[*][?(@.name=='Transparent')].attrs" '["#[repr(transparent)]"]'
912
#[repr(transparent)]
1013
pub struct Transparent(pub i64);
1114

12-
//@ is "$.index[*][?(@.name=='TransparentNonPub')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
15+
// Here the non-1-ZST field isn't public, so the attribute isn't included.
16+
//
17+
//@ has "$.index[*][?(@.name=='TransparentNonPub')]"
18+
//@ is "$.index[*][?(@.name=='TransparentNonPub')].attrs" '[]'
1319
#[repr(transparent)]
1420
pub struct TransparentNonPub(i64);
1521

16-
//@ is "$.index[*][?(@.name=='AllZst')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
22+
// Only 1-ZST fields here, and one of them is public.
23+
// We expect `#[repr(transparent)]` in the attributes.
24+
//
25+
//@ is "$.index[*][?(@.name=='AllZst')].attrs" '["#[repr(transparent)]"]'
1726
#[repr(transparent)]
1827
pub struct AllZst<'a>(pub core::marker::PhantomData<&'a ()>, ());
1928

20-
//@ is "$.index[*][?(@.name=='AllZstNotPublic')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
29+
// Only 1-ZST fields here but none of them are public.
30+
// The attribute isn't included.
31+
//
32+
//@ has "$.index[*][?(@.name=='AllZstNotPublic')]"
33+
//@ is "$.index[*][?(@.name=='AllZstNotPublic')].attrs" '[]'
2134
#[repr(transparent)]
2235
pub struct AllZstNotPublic<'a>(core::marker::PhantomData<&'a ()>, ());

0 commit comments

Comments
 (0)