Skip to content

Commit 67e9486

Browse files
committed
rustdoc: Use own logic to print #[repr(..)] attributes in JSON output.
1 parent f9e0239 commit 67e9486

File tree

8 files changed

+188
-4
lines changed

8 files changed

+188
-4
lines changed

src/librustdoc/clean/types.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,15 @@ impl Item {
772772
.other_attrs
773773
.iter()
774774
.filter_map(|attr| {
775-
if keep_as_is {
775+
// We have separate pretty-printing logic for `#[repr(..)]` attributes.
776+
// For example, there are circumstances where `#[repr(transparent)]` is applied
777+
// but should not be publicly shown in rustdoc because it isn't public API.
778+
if keep_as_is
779+
&& !matches!(
780+
attr,
781+
rustc_hir::Attribute::Parsed(rustc_attr_parsing::AttributeKind::Repr(..))
782+
)
783+
{
776784
Some(rustc_hir_pretty::attribute_to_string(&tcx, attr))
777785
} else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
778786
Some(
@@ -786,8 +794,7 @@ impl Item {
786794
}
787795
})
788796
.collect();
789-
if !keep_as_is
790-
&& let Some(def_id) = self.def_id()
797+
if let Some(def_id) = self.def_id()
791798
&& let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_()
792799
{
793800
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 = 40;
33+
pub const FORMAT_VERSION: u32 = 41;
3434

3535
/// The root of the emitted JSON blob.
3636
///
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![no_std]
2+
3+
//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[repr(align(4))]"]'
4+
#[repr(align(4))]
5+
pub struct Aligned {
6+
a: i8,
7+
b: i64,
8+
}

tests/rustdoc-json/attrs/repr_c.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![no_std]
2+
3+
//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[repr(C)]"]'
4+
#[repr(C)]
5+
pub struct ReprCStruct(pub i64);
6+
7+
//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[repr(C)]"]'
8+
#[repr(C)]
9+
pub enum ReprCEnum {
10+
First,
11+
}
12+
13+
//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[repr(C)]"]'
14+
#[repr(C)]
15+
pub union ReprCUnion {
16+
pub left: i64,
17+
pub right: u64,
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#![no_std]
2+
3+
// Combinations of `#[repr(..)]` attributes.
4+
// Rustdoc JSON emits normalized output, regardless of the original source.
5+
6+
//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[repr(C, i8)]"]'
7+
#[repr(C, i8)]
8+
pub enum ReprCI8 {
9+
First,
10+
}
11+
12+
//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[repr(C, i16)]"]'
13+
#[repr(C)]
14+
#[repr(i16)]
15+
pub enum SeparateReprCI16 {
16+
First,
17+
}
18+
19+
//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[repr(C, usize)]"]'
20+
#[repr(usize, C)]
21+
pub enum ReversedReprCUsize {
22+
First,
23+
}
24+
25+
//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[repr(C, packed(1))]"]'
26+
#[repr(C, packed)]
27+
pub struct ReprCPacked {
28+
a: i8,
29+
b: i64,
30+
}
31+
32+
//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
33+
#[repr(C)]
34+
#[repr(packed(2))]
35+
pub struct SeparateReprCPacked {
36+
a: i8,
37+
b: i64,
38+
}
39+
40+
//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
41+
#[repr(packed(2), C)]
42+
pub struct ReversedReprCPacked {
43+
a: i8,
44+
b: i64,
45+
}
46+
47+
//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[repr(C, align(16))]"]'
48+
#[repr(C, align(16))]
49+
pub struct ReprCAlign {
50+
a: i8,
51+
b: i64,
52+
}
53+
54+
//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
55+
#[repr(C)]
56+
#[repr(align(2))]
57+
pub struct SeparateReprCAlign {
58+
a: i8,
59+
b: i64,
60+
}
61+
62+
//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
63+
#[repr(align(2), C)]
64+
pub struct ReversedReprCAlign {
65+
a: i8,
66+
b: i64,
67+
}
68+
69+
//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
70+
#[repr(C, align(16), isize)]
71+
pub enum AlignedExplicitRepr {
72+
First,
73+
}
74+
75+
//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
76+
#[repr(isize, C, align(16))]
77+
pub enum ReorderedAlignedExplicitRepr {
78+
First,
79+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![no_std]
2+
3+
//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[repr(i8)]"]'
4+
#[repr(i8)]
5+
pub enum I8 {
6+
First,
7+
}
8+
9+
//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[repr(i32)]"]'
10+
#[repr(i32)]
11+
pub enum I32 {
12+
First,
13+
}
14+
15+
//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[repr(usize)]"]'
16+
#[repr(usize)]
17+
pub enum Usize {
18+
First,
19+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![no_std]
2+
3+
// Note the normalization:
4+
// `#[repr(packed)]` in source becomes `#[repr(packed(1))]` in rustdoc JSON.
5+
//
6+
//@ is "$.index[*][?(@.name=='Packed')].attrs" '["#[repr(packed(1))]"]'
7+
#[repr(packed)]
8+
pub struct Packed {
9+
a: i8,
10+
b: i64,
11+
}
12+
13+
//@ is "$.index[*][?(@.name=='PackedAligned')].attrs" '["#[repr(packed(4))]"]'
14+
#[repr(packed(4))]
15+
pub struct PackedAligned {
16+
a: i8,
17+
b: i64,
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![no_std]
2+
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
7+
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)]"]'
12+
#[repr(transparent)]
13+
pub struct Transparent(pub i64);
14+
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" '[]'
19+
#[repr(transparent)]
20+
pub struct TransparentNonPub(i64);
21+
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)]"]'
26+
#[repr(transparent)]
27+
pub struct AllZst<'a>(pub core::marker::PhantomData<&'a ()>, ());
28+
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" '[]'
34+
#[repr(transparent)]
35+
pub struct AllZstNotPublic<'a>(core::marker::PhantomData<&'a ()>, ());

0 commit comments

Comments
 (0)