Skip to content

rustdoc-json: Structured attributes #142936

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

aDotInTheVoid
Copy link
Member

@aDotInTheVoid aDotInTheVoid commented Jun 23, 2025

Implements #141358.

This has 2 primary benefits.

  1. For rustdoc-json consumers, they no longer need to parse strings of attributes, but it's there in a structured and normalized way. CC @obi1kenobi
  2. For rustc conributors, the output of HIR pretty printing is no longer a versioned thing in the output. People can work on Tracking issue: Attribute refactor #131229 without needing to bump FORMAT_VERSION. CC @jdonszelmann @JonathanBrouwer.

(Over time, as the attribute refractor continues, I expect we'll add new things to rustdoc_json_types::Attribute. But this can be done separately to the rustc changes).

Todo before being mergable:

  • Update test assertions.
  • Fix modeling of #[repr].
  • Add tests of #[doc(hidden)] in Item::attrs (probably in a seperate PR). I'm gonna punt this to a future PR
  • Documentation.

@rustbot
Copy link
Collaborator

rustbot commented Jun 23, 2025

r? @notriddle

rustbot has assigned @notriddle.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Jun 23, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 23, 2025

rustdoc-json-types is a public (although nightly-only) API. If possible, consider changing src/librustdoc/json/conversions.rs; otherwise, make sure you bump the FORMAT_VERSION constant.

cc @CraftSpider, @aDotInTheVoid, @Enselic, @obi1kenobi

@jdonszelmann
Copy link
Contributor

Awesome alona! I'll take a proper look tomorrow <3

@aDotInTheVoid aDotInTheVoid added the A-attributes Area: Attributes (`#[…]`, `#![…]`) label Jun 23, 2025
@rust-log-analyzer

This comment has been minimized.

Copy link
Member

@obi1kenobi obi1kenobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this!

In the near term cargo-semver-checks will have to internally re-stringify the attributes just for code compatibility with prior rustdoc JSON versions. But I look forward to the day when I can rip all that out and enjoy the structured form instead!

@bors
Copy link
Collaborator

bors commented Jun 24, 2025

☔ The latest upstream changes (presumably #142929) made this pull request unmergeable. Please resolve the merge conflicts.

@aDotInTheVoid aDotInTheVoid changed the title WIP: rustdoc-json: Structured attributes rustdoc-json: Structured attributes Jun 24, 2025
@aDotInTheVoid aDotInTheVoid marked this pull request as ready for review June 24, 2025 19:27
@rustbot
Copy link
Collaborator

rustbot commented Jun 24, 2025

r? @GuillaumeGomez

rustbot has assigned @GuillaumeGomez.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot
Copy link
Collaborator

rustbot commented Jun 24, 2025

These commits modify tests/rustdoc-json.
rustdoc-json is a public (but unstable) interface.

Please ensure that if you've changed the output:

  • It's intentional.
  • The FORMAT_VERSION in src/librustdoc-json-types is bumped if necessary.

cc @aDotInTheVoid, @obi1kenobi

@rust-cloud-vms rust-cloud-vms bot force-pushed the rdj-shatts-forrealthistime branch from 1d4b795 to c912543 Compare June 24, 2025 19:27
@aDotInTheVoid
Copy link
Member Author

Now no longer WIP.

When you're happy with it, let me know but don't r+, as I'll need to squash commits.

@rust-log-analyzer

This comment has been minimized.

Copy link
Member

@obi1kenobi obi1kenobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Looking forward to this!

Comment on lines 759 to 760
// NoMangle is special cased, as it's currently the only structured
// attribute that we want to appear in HTML output.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a separate concern unrelated to this PR, perhaps HTML output should list both #[no_mangle] and #[export_name] in their edition 2024 form i.e. wrapped in unsafe?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please open an issue then so it's not forgotten.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already track this in #142835 (comment) (jana is assigned)

Copy link
Member

@GuillaumeGomez GuillaumeGomez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me. It's nice to see less is_json conditions in the common code. :)

@bors
Copy link
Collaborator

bors commented Jun 27, 2025

☔ The latest upstream changes (presumably #143074) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-cloud-vms rust-cloud-vms bot force-pushed the rdj-shatts-forrealthistime branch 2 times, most recently from c5a697c to df1d953 Compare July 7, 2025 21:28
@rust-log-analyzer

This comment has been minimized.

/// The contents of a `#[repr(...)]` attribute.
///
/// Used in [`Attribute::Repr`].
pub struct AttributeRepr {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CC @workingjubilee, how does this look for a structured representation of a #[repr] attribute?

@rust-log-analyzer

This comment has been minimized.

Implements rust-lang#141358.

This has 2 primary benefits:

1. For rustdoc-json consumers, they no longer need to parse strings of
   attributes, but it's there in a structured and normalized way.
2. For rustc contributors, the output of HIR pretty printing is no
   longer a versioned thing in the output. People can work on
   rust-lang#131229 without needing to bump `FORMAT_VERSION`.

(Over time, as the attribute refractor continues, I expect we'll add new
things to `rustdoc_json_types::Attribute`. But this can be done
separately to the rustc changes).
@rust-cloud-vms rust-cloud-vms bot force-pushed the rdj-shatts-forrealthistime branch from d772cf6 to 244351c Compare July 7, 2025 22:30
@aDotInTheVoid
Copy link
Member Author

Rebased. I think this is worth reviewing again, as it's changed it response to changes to rustc since intially opening.

@rustbot ready.

Copy link
Member

@obi1kenobi obi1kenobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, big fan of this overall. A handful of small typo fix nits.

// NoMangle is special cased, as it appears in HTML output, and we want to show it in source form, not HIR printing.
// It is also used by cargo-semver-checks.
else if let hir::Attribute::Parsed(AttributeKind::NoMangle(..)) = attr {
} else if let hir::Attribute::Parsed(AttributeKind::NoMangle(..)) = attr {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit of a drive-by, but should we update these to Rust 2024 edition form? #[unsafe(no_mangle)], #[unsafe(export_name = ...)] etc.

Comment on lines +780 to +781
} else if !attr.has_any_name(ALLOWED_ATTRIBUTES) {
None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, since I'm a bit confused here:

  • I see ALLOWED_ATTRIBUTES contains sym::non_exhaustive.
  • I see #[non_exhaustive] in the else if arm right above this.

Is there a case where a non-exhaustive might slip through the earlier check and then match the .has_any_name()?

};

Some(match kind {
AK::Deprecation { .. } => return None, // Handled seperatly into Item::deprecation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo fix:

Suggested change
AK::Deprecation { .. } => return None, // Handled seperatly into Item::deprecation.
AK::Deprecation { .. } => return None, // Handled separately into Item::deprecation.

Comment on lines +929 to +931
AK::TargetFeature(features, _span) => Attribute::TargetFeature(
features.iter().map(|(feat, _span)| feat.to_string()).collect(),
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads-up: there's an RFC being prepared to add two flavors of #[target_feature]: enable and force, each of which has its own list of feature names.

We don't have to make a proactive change to make that happen, but I think the RFC has decent odds of passing so I wanted to mention it for general awareness & in case you felt you wanted to change anything.

/// Information about the item’s deprecation, if present.
pub deprecation: Option<Deprecation>,
/// The type-specific fields describing this item.
pub inner: ItemEnum,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
/// An attribute, eg `#[repr(C)]`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
/// An attribute, eg `#[repr(C)]`
/// An attribute, e.g. `#[repr(C)]`

Comment on lines +239 to +240
/// Things here are explicitly *not* covered by the [`FORMAT_VERSION`]
/// constant, and may change without bumping the format version.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Since #[doc(hidden)] is super critical to cargo-semver-checks I hope we can be mindful of it with respect to this clause. I wouldn't insist on special-casing it here and I know you are planning to tackle it soon — just wanted to raise a possible concern pre-emptively :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants