rustdoc: Use own logic to print #[repr(..)]
attributes in JSON output.
This commit is contained in:
parent
d93f678fa5
commit
bafdbcadd5
10 changed files with 82 additions and 43 deletions
|
@ -768,12 +768,22 @@ impl Item {
|
|||
.iter()
|
||||
.filter_map(|attr| {
|
||||
if is_json {
|
||||
if matches!(attr, hir::Attribute::Parsed(AttributeKind::Deprecation { .. })) {
|
||||
// rustdoc-json stores this in `Item::deprecation`, so we
|
||||
// don't want it it `Item::attrs`.
|
||||
None
|
||||
} else {
|
||||
Some(rustc_hir_pretty::attribute_to_string(&tcx, attr))
|
||||
match attr {
|
||||
hir::Attribute::Parsed(AttributeKind::Deprecation { .. }) => {
|
||||
// rustdoc-json stores this in `Item::deprecation`, so we
|
||||
// don't want it it `Item::attrs`.
|
||||
None
|
||||
}
|
||||
rustc_hir::Attribute::Parsed(rustc_attr_parsing::AttributeKind::Repr(
|
||||
..,
|
||||
)) => {
|
||||
// We have separate pretty-printing logic for `#[repr(..)]` attributes.
|
||||
// For example, there are circumstances where `#[repr(transparent)]`
|
||||
// is applied but should not be publicly shown in rustdoc
|
||||
// because it isn't public API.
|
||||
None
|
||||
}
|
||||
_ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
|
||||
}
|
||||
} else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
|
||||
Some(
|
||||
|
@ -789,8 +799,7 @@ impl Item {
|
|||
.collect();
|
||||
|
||||
// Add #[repr(...)]
|
||||
if !is_json
|
||||
&& let Some(def_id) = self.def_id()
|
||||
if let Some(def_id) = self.def_id()
|
||||
&& let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_()
|
||||
{
|
||||
let adt = tcx.adt_def(def_id);
|
||||
|
|
|
@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
|
|||
/// This integer is incremented with every breaking change to the API,
|
||||
/// and is returned along with the JSON blob as [`Crate::format_version`].
|
||||
/// Consuming code should assert that this value matches the format version(s) that it supports.
|
||||
pub const FORMAT_VERSION: u32 = 42;
|
||||
pub const FORMAT_VERSION: u32 = 43;
|
||||
|
||||
/// The root of the emitted JSON blob.
|
||||
///
|
||||
|
@ -120,9 +120,23 @@ pub struct Item {
|
|||
pub docs: Option<String>,
|
||||
/// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs
|
||||
pub links: HashMap<String, Id>,
|
||||
/// Stringified versions of parsed attributes on this item.
|
||||
/// Essentially debug printed (e.g. `#[inline]` becomes something similar to `#[attr="Inline(Hint)"]`).
|
||||
/// Equivalent to the hir pretty-printing of attributes.
|
||||
/// Attributes on this item.
|
||||
///
|
||||
/// Does not include `#[deprecated]` attributes: see the [`Self::deprecation`] field instead.
|
||||
///
|
||||
/// Some attributes appear in pretty-printed Rust form, regardless of their formatting
|
||||
/// in the original source code. For example:
|
||||
/// - `#[non_exhaustive]` and `#[must_use]` are represented as themselves.
|
||||
/// - `#[no_mangle]` and `#[export_name]` are also represented as themselves.
|
||||
/// - `#[repr(C)]` and other reprs also appear as themselves,
|
||||
/// though potentially with a different order: e.g. `repr(i8, C)` may become `repr(C, i8)`.
|
||||
/// Multiple repr attributes on the same item may be combined into an equivalent single attr.
|
||||
///
|
||||
/// Other attributes may appear debug-printed. For example:
|
||||
/// - `#[inline]` becomes something similar to `#[attr="Inline(Hint)"]`.
|
||||
///
|
||||
/// As an internal implementation detail subject to change, this debug-printing format
|
||||
/// is currently equivalent to the HIR pretty-printing of parsed attributes.
|
||||
pub attrs: Vec<String>,
|
||||
/// Information about the item’s deprecation, if present.
|
||||
pub deprecation: Option<Deprecation>,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![no_std]
|
||||
|
||||
//@ is "$.index[?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='Aligned')].attrs" '["#[repr(align(4))]"]'
|
||||
#[repr(align(4))]
|
||||
pub struct Aligned {
|
||||
a: i8,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#![no_std]
|
||||
|
||||
//@ is "$.index[?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReprCStruct')].attrs" '["#[repr(C)]"]'
|
||||
#[repr(C)]
|
||||
pub struct ReprCStruct(pub i64);
|
||||
|
||||
//@ is "$.index[?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReprCEnum')].attrs" '["#[repr(C)]"]'
|
||||
#[repr(C)]
|
||||
pub enum ReprCEnum {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReprCUnion')].attrs" '["#[repr(C)]"]'
|
||||
#[repr(C)]
|
||||
pub union ReprCUnion {
|
||||
pub left: i64,
|
||||
|
|
|
@ -1,34 +1,35 @@
|
|||
#![no_std]
|
||||
|
||||
// Combinations of `#[repr(..)]` attributes.
|
||||
// Rustdoc JSON emits normalized output, regardless of the original source.
|
||||
|
||||
//@ is "$.index[?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReprCI8')].attrs" '["#[repr(C, i8)]"]'
|
||||
#[repr(C, i8)]
|
||||
pub enum ReprCI8 {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '["#[repr(C, i16)]"]'
|
||||
#[repr(C)]
|
||||
#[repr(i16)]
|
||||
pub enum SeparateReprCI16 {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '["#[repr(C, usize)]"]'
|
||||
#[repr(usize, C)]
|
||||
pub enum ReversedReprCUsize {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '["#[repr(C, packed(1))]"]'
|
||||
#[repr(C, packed)]
|
||||
pub struct ReprCPacked {
|
||||
a: i8,
|
||||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
|
||||
#[repr(C)]
|
||||
#[repr(packed(2))]
|
||||
pub struct SeparateReprCPacked {
|
||||
|
@ -36,21 +37,21 @@ pub struct SeparateReprCPacked {
|
|||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
|
||||
#[repr(packed(2), C)]
|
||||
pub struct ReversedReprCPacked {
|
||||
a: i8,
|
||||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '["#[repr(C, align(16))]"]'
|
||||
#[repr(C, align(16))]
|
||||
pub struct ReprCAlign {
|
||||
a: i8,
|
||||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
|
||||
#[repr(C)]
|
||||
#[repr(align(2))]
|
||||
pub struct SeparateReprCAlign {
|
||||
|
@ -58,20 +59,20 @@ pub struct SeparateReprCAlign {
|
|||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
|
||||
#[repr(align(2), C)]
|
||||
pub struct ReversedReprCAlign {
|
||||
a: i8,
|
||||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
|
||||
#[repr(C, align(16), isize)]
|
||||
pub enum AlignedExplicitRepr {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
|
||||
#[repr(isize, C, align(16))]
|
||||
pub enum ReorderedAlignedExplicitRepr {
|
||||
First,
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#![no_std]
|
||||
|
||||
//@ is "$.index[?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='I8')].attrs" '["#[repr(i8)]"]'
|
||||
#[repr(i8)]
|
||||
pub enum I8 {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='I32')].attrs" '["#[repr(i32)]"]'
|
||||
#[repr(i32)]
|
||||
pub enum I32 {
|
||||
First,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='Usize')].attrs" '["#[repr(usize)]"]'
|
||||
#[repr(usize)]
|
||||
pub enum Usize {
|
||||
First,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#![no_std]
|
||||
|
||||
// Note the normalization:
|
||||
// `#[repr(packed)]` in has the implict "1" in rustdoc JSON.
|
||||
|
||||
//@ is "$.index[?(@.name=='Packed')].attrs" '["#[attr = Repr([ReprPacked(Align(1 bytes))])]\n"]'
|
||||
// `#[repr(packed)]` in source becomes `#[repr(packed(1))]` in rustdoc JSON.
|
||||
//
|
||||
//@ is "$.index[?(@.name=='Packed')].attrs" '["#[repr(packed(1))]"]'
|
||||
#[repr(packed)]
|
||||
pub struct Packed {
|
||||
a: i8,
|
||||
b: i64,
|
||||
}
|
||||
|
||||
//@ is "$.index[?(@.name=='PackedAligned')].attrs" '["#[attr = Repr([ReprPacked(Align(4 bytes))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='PackedAligned')].attrs" '["#[repr(packed(4))]"]'
|
||||
#[repr(packed(4))]
|
||||
pub struct PackedAligned {
|
||||
a: i8,
|
||||
|
|
|
@ -1,22 +1,37 @@
|
|||
#![no_std]
|
||||
|
||||
// Rustdoc JSON currently includes `#[repr(transparent)]`
|
||||
// even if the transparency is not part of the public API
|
||||
// Rustdoc JSON *only* includes `#[repr(transparent)]`
|
||||
// if the transparency is public API:
|
||||
// - if a non-1-ZST field exists, it has to be public
|
||||
// - otherwise, all fields are 1-ZST and at least one of them is public
|
||||
//
|
||||
// https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
|
||||
// More info: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
|
||||
|
||||
//@ is "$.index[?(@.name=='Transparent')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
|
||||
// Here, the non-1-ZST field is public.
|
||||
// We expect `#[repr(transparent)]` in the attributes.
|
||||
//
|
||||
//@ is "$.index[?(@.name=='Transparent')].attrs" '["#[repr(transparent)]"]'
|
||||
#[repr(transparent)]
|
||||
pub struct Transparent(pub i64);
|
||||
|
||||
//@ is "$.index[?(@.name=='TransparentNonPub')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
|
||||
// Here the non-1-ZST field isn't public, so the attribute isn't included.
|
||||
//
|
||||
//@ has "$.index[?(@.name=='TransparentNonPub')]"
|
||||
//@ is "$.index[?(@.name=='TransparentNonPub')].attrs" '[]'
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentNonPub(i64);
|
||||
|
||||
//@ is "$.index[?(@.name=='AllZst')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
|
||||
// Only 1-ZST fields here, and one of them is public.
|
||||
// We expect `#[repr(transparent)]` in the attributes.
|
||||
//
|
||||
//@ is "$.index[?(@.name=='AllZst')].attrs" '["#[repr(transparent)]"]'
|
||||
#[repr(transparent)]
|
||||
pub struct AllZst<'a>(pub core::marker::PhantomData<&'a ()>, ());
|
||||
|
||||
//@ is "$.index[?(@.name=='AllZstNotPublic')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
|
||||
// Only 1-ZST fields here but none of them are public.
|
||||
// The attribute isn't included.
|
||||
//
|
||||
//@ has "$.index[?(@.name=='AllZstNotPublic')]"
|
||||
//@ is "$.index[?(@.name=='AllZstNotPublic')].attrs" '[]'
|
||||
#[repr(transparent)]
|
||||
pub struct AllZstNotPublic<'a>(core::marker::PhantomData<&'a ()>, ());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[repr(i32)]
|
||||
//@ is "$.index[?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(i32)]"]'
|
||||
pub enum Foo {
|
||||
//@ is "$.index[?(@.name=='Struct')].inner.variant.discriminant" null
|
||||
//@ count "$.index[?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[repr(u32)]
|
||||
//@ is "$.index[?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(U32))])]\n"]'
|
||||
//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(u32)]"]'
|
||||
pub enum Foo {
|
||||
//@ is "$.index[?(@.name=='Tuple')].inner.variant.discriminant" null
|
||||
//@ count "$.index[?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue