Skip to content
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

rustdoc: Output target feature information #139393

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

Conversation

willglynn
Copy link

#[target_feature] attributes refer to a target-specific list of features. Enabling certain features can imply enabling other features. Certain features are always enabled on certain targets, since they are required by the target's ABI. Features can also be enabled indirectly based on other compiler flags.

Feature information is ultimately known to rustc. Rather than force external tools to track it – which may be wildly impractical due to -C target-cpu – have rustdoc output rustc's feature data.

This change is motivated by obi1kenobi/cargo-semver-checks#1246, which intends to detect semver hazards caused by #[target_feature].

@rustbot
Copy link
Collaborator

rustbot commented Apr 4, 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. labels Apr 4, 2025
@rust-log-analyzer

This comment has been minimized.

@willglynn willglynn force-pushed the rustdoc_output_target_feature_information branch 2 times, most recently from 7c6a12b to cb2b075 Compare April 7, 2025 17:30
@willglynn willglynn marked this pull request as ready for review April 7, 2025 18:23
@rustbot
Copy link
Collaborator

rustbot commented Apr 7, 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

@willglynn
Copy link
Author

I'm unsure about two topics here:

  1. Does adding a field count as a backwards incompatible change for rustdoc-json-types purposes? I decided no due to the absence of #[serde(deny_unknown_fields)], so I did not increment FORMAT_VERSION.
  2. Is it acceptable to output information about unstable target features from a stable toolchain? I decided yes so I unconditionally output both stable and unstable user-specifiable target features, and I decided that the stability distinction was important so I provide the associated language feature for any unstable target features.

Besides stable and unstable, there is also rustc_target::target_features::Stability::Forbidden:

    /// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be
    /// set in the target spec. It is never set in `cfg(target_feature)`. Used in
    /// particular for features are actually ABI configuration flags (not all targets are as nice as
    /// RISC-V and have an explicit way to set the ABI separate from target features).
    Forbidden { reason: &'static str },

I decided forbidden features are effectively internal implementation details (unreachable by the user) and so I drop them from the list.

@Enselic
Copy link
Member

Enselic commented Apr 8, 2025

A new struct field is backwards compatible (edit: if it's Option or uses something like #[serde(default)] but we probably want neither in this case) but also a new FORMAT_VERSION.

`#[target_feature]` attributes refer to a target-specific list of
features. Enabling certain features can imply enabling other features.
Certain features are always enabled on certain targets, since they are
required by the target's ABI. Features can also be enabled indirectly
based on other compiler flags.

Feature information is ultimately known to `rustc`. Rather than force
external tools to track it -- which may be wildly impractical due to
`-C target-cpu` -- have `rustdoc` output `rustc`'s feature data.
@willglynn willglynn force-pushed the rustdoc_output_target_feature_information branch from cb2b075 to 58fd7b4 Compare April 8, 2025 03:06
@willglynn
Copy link
Author

Got it. Is there a better way to phrase this requirement, and if so, would it belong in this PR?

/// The version of JSON output that this crate represents.
///
/// 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 = 44;

@Enselic
Copy link
Member

Enselic commented Apr 8, 2025

Looking closer at your code I think this is actually a breaking change since the new field is not Option and does not use something like #[serde(default)] but I don't think we want anything like that in this case.

To be clear: I expect JSON from an old nightly to fail to deserialize into the new struct, but I expect JSON from a new nightly to successfully deserialize into the old struct.

@willglynn
Copy link
Author

Oh, sure, I was thinking about the old-reading-new case and not the new-reading-old case. You're absolutely right that this is a breaking change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants