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

Support multiple stability attributes on items #131824

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

dianne
Copy link
Contributor

@dianne dianne commented Oct 17, 2024

Motivation

Many unstable library items require the stabilization of multiple features before they can be stabilized. By allowing them to be annotated with multiple #[unstable] attributes, this prevents their accidental stabilization when some of those features are stabilized, and helps mitigate upgrade pains for unstable toolchain users.

New stability attribute semantics

In the most recent commit, the way it works is:

  • If any #[unstable] attribute is present on an item, it is unstable. Likewise, any #[rustc_const_unstable] marks an item as const-unstable, and any #[rustc_default_body_unstable] marks it as default body-unstable.
  • In order to use an unstable item, all feature gates specified by its #[unstable] attributes must be enabled. Conceptually, this is because it depends on multiple unstable features. Practically, this also means nightly toolchain users are less likely to need to replace one unstable feature gate with another in their crate-level attributes.
  • Multiple #[stable] attributes may be present to document the stabilized features an item depended on. The stabilization version of an item is the most recent stabilization version in present #[stable] attributes. Likewise, #[stable] attributes may be present on an unstable item to document stabilized features it formerly depended on. From what I understand, this is non-essential, but I figured I'd implement it anyway so the libs-api team can decide whether it's helpful or confusing. This is done in a separate commit, so I can revert it if desired.

New syntactic constraints

  • As a sanity check, an item is not allowed to have multiple stability attributes for the same feature.
  • At most one #[unstable] attribute on an item may have a reason provided (and likewise for #[rustc_const_unstable] and #[rustc_default_body_unstable]). At a glance, the reason meta-item was used to describe the reason for an item being unstable, rather than an individual feature it depends on. Enforcing this makes the diagnostic formatting much cleaner.
  • If any #[unstable] attribute on an item has a soft marker, it must be present on all #[unstable] attributes on that item. Items can't be partially soft-unstable, and this helps prevent accidentally making a soft-unstable item unusable on stable when stabilizing one of the features it requires.

Fixes #94770

Based on #94988

PR for a diagnostic formatting change this uses: #132544

I have some notes I'd like input on, in case they're messy or contentious. I tried to isolate some of these into their own commits, so see those for more info (sorry some of the commits are still giant! stability attributes seem to be used in a lot of places).

  • Stability structs are specialized to how they're used for stability checking and rustdoc. rustc_passes::lib_features also reads stability attributes, but it parses them itself. I considered it out of the scope of this PR refactor that too, but if attribute handling is reworked to be more unified in the future, this may need further adjustment (but hopefully not too much).
  • This supports multiple #[stable] attributes, and a mix of #[stable] and #[unstable], in case that's helpful for tracking which features library items depended on as they stabilize (and because it's less difficult to reword E0544 this way).
  • This changes E0544 (multiple stability levels). Should the error code be different now, or is reusing the same one okay? rustc_passes::lib_features catches instances of the same feature being given different stability levels or stabilization versions, so the only error it uniquely catches is when the same stability level is given multiple times (potentially with different reasons, issue numbers, implied_bys, or rustc_allowed_through_unstable_moduless).
  • Under the assumption that most library items will still have at most one #[unstable] attribute, this uses SmallVec<[_; 1]> for storage. Is this assumption sound? I haven't done any performance testing.
  • To avoid reporting multiple errors for a single unstable same item use (while messing minimally with diagnostic machinery for unstable language features), I've separated out the diagnostics for library features. I'm not sure about the formatting, though; I think it might be too complicated. This also unifies handling for unstable, soft-unstable, const-unstable, and default-body-unstable diagnostics, so some of those have information now that they were lacking before.
  • feature_err_issue is no longer used for library features. I've left it for now since feature_warn_issue is in a similar state.
  • report_unstable and soft_unstable could now take a crate-level attribute injection span to let check_optional_stability provide that when possible for suggestions on nightly. At the moment it doesn't, since it'd be even more test stderr updates (including a new error emitted from ui-fulldeps/hash-stable-is-unstable.rs since it wouldn't get de-duplicated).
  • Since StabilityLevel no longer has Copy, stability structs are now arena-allocated. I'm not sure what the performance implications are. I'm sure you could get away with putting less in the arena by doing something more complicated, if it's an issue.

This doesn't update any libraries to add additional unstable attributes to items that should have them.

@rustbot
Copy link
Collaborator

rustbot commented Oct 17, 2024

r? @wesleywiser

rustbot has assigned @wesleywiser.
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 S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Oct 17, 2024
@rustbot
Copy link
Collaborator

rustbot commented Oct 17, 2024

Some changes occurred in src/librustdoc/clean/types.rs

cc @camelid

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Oct 22, 2024

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

@bors
Copy link
Contributor

bors commented Oct 23, 2024

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

@bors
Copy link
Contributor

bors commented Oct 24, 2024

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

@bors
Copy link
Contributor

bors commented Oct 26, 2024

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

@rustbot
Copy link
Collaborator

rustbot commented Oct 26, 2024

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@dianne
Copy link
Contributor Author

dianne commented Oct 26, 2024

cc @RalfJung @compiler-errors This rebase was pretty substantial and required some minor refactors. Would either of you mind giving the const-stability parts a look to make sure they make sense and don't go against planned future changes?

cc @rust-lang/libs-api I realize I should probably ping here as well. Does the design supporting a mix of unstable/stable attributes sound good? I'll try documenting it in the dev guide and std dev guide once that's finalized.

@bors
Copy link
Contributor

bors commented Oct 27, 2024

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

@RalfJung
Copy link
Member

The PR should explain what the semantics are of having multiple unstable attributes. Do all gates need to be active to use the feature, or only some?

This supports multiple #[stable] attributes, and a mix of #[stable] and #[unstable], in case that's helpful for tracking which features library items depended on as they stabilize (and because it's less difficult to reword E0544 this way).

That sounds really strange. What is the semantics of this? And what is the point?

compiler/rustc_const_eval/src/check_consts/check.rs Outdated Show resolved Hide resolved
compiler/rustc_attr/src/builtin.rs Outdated Show resolved Hide resolved
Unstable { unstables: SmallVec<[Unstability; 1]> },
/// For functions with no explicit const-stability attribute that require checking recursive
/// const stability. This is either an unmarked const fn or a `const_stable_indirect` intrinsic.
Implicit,
Copy link
Member

Choose a reason for hiding this comment

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

Please rename this to ImplicitUnstable, because we never want anything to be "implicitly stable".

Also FWIW this variant will disappear when I have the time to continue working on the const stability checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Do you think this should be blocked on that being merged?

Copy link
Member

Choose a reason for hiding this comment

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

Do you think this should be blocked on that being merged?

Not sure which timeline you are on. I don't know when I will get around to writing my planned PRs.

Copy link
Member

Choose a reason for hiding this comment

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

My PR is now up: #132541

tests/ui/consts/const-unstable-intrinsic.stderr Outdated Show resolved Hide resolved
@dianne
Copy link
Contributor Author

dianne commented Oct 27, 2024

The PR should explain what the semantics are of having multiple unstable attributes. Do all gates need to be active to use the feature, or only some?

This supports multiple #[stable] attributes, and a mix of #[stable] and #[unstable], in case that's helpful for tracking which features library items depended on as they stabilize (and because it's less difficult to reword E0544 this way).

That sounds really strange. What is the semantics of this? And what is the point?

I've updated the PR description to address this. To your second point, I'm working off of this specification. Treating it as a matter of preference, I decided to implement it both with and without support for multiple #[stable] attributes in separate commits so that I'd have an implementation to point to before asking which approach is nicer. I'll work on addressing your review comments shortly. Thank you for giving this a look!

@RalfJung
Copy link
Member

The updated PR description is great, thanks. :)

Personally I don't think multiple stable attributes, or both stable and unstable, are worth it. But let's see what t-libs-api thinks.

@RalfJung RalfJung added I-libs-api-nominated Nominated for discussion during a libs-api team meeting. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Oct 28, 2024
@bors
Copy link
Contributor

bors commented Oct 28, 2024

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

@bors
Copy link
Contributor

bors commented Nov 1, 2024

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

@RalfJung
Copy link
Member

RalfJung commented Nov 3, 2024

That will also make reviewing this PR a lot easier by reducing the noise in the diff. :)

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Nov 3, 2024
…ckticks, r=compiler-errors

Use backticks instead of single quotes for library feature names in diagnostics

This PR changes the text of library feature errors for using unstable or body-unstable items. Displaying library feature names in backticks is consistent with other diagnostics (e.g. those from `rustc_passes`) and with the `reason`s on unstable attributes in the library. Additionally, this simplifies diagnostics when supporting multiple unstable attributes on items (see rust-lang#131824) since `DiagSymbolList` also displays symbols using backticks.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Nov 4, 2024
…ckticks, r=compiler-errors

Use backticks instead of single quotes for library feature names in diagnostics

This PR changes the text of library feature errors for using unstable or body-unstable items. Displaying library feature names in backticks is consistent with other diagnostics (e.g. those from `rustc_passes`) and with the `reason`s on unstable attributes in the library. Additionally, this simplifies diagnostics when supporting multiple unstable attributes on items (see rust-lang#131824) since `DiagSymbolList` also displays symbols using backticks.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Nov 4, 2024
Rollup merge of rust-lang#132544 - dianne:unstable-library-feature-backticks, r=compiler-errors

Use backticks instead of single quotes for library feature names in diagnostics

This PR changes the text of library feature errors for using unstable or body-unstable items. Displaying library feature names in backticks is consistent with other diagnostics (e.g. those from `rustc_passes`) and with the `reason`s on unstable attributes in the library. Additionally, this simplifies diagnostics when supporting multiple unstable attributes on items (see rust-lang#131824) since `DiagSymbolList` also displays symbols using backticks.
@bors
Copy link
Contributor

bors commented Nov 4, 2024

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

@bors
Copy link
Contributor

bors commented Nov 5, 2024

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

@jdonszelmann
Copy link
Contributor

jdonszelmann commented Nov 5, 2024

I just learned about this PR, and I just wanted to note that this will be a giant conflict with #131229. That should in no way stop us from going forward with this, but it is something that's good to know. Whoever happens to merge their changes first will force the other to retrofit their changes onto it haha, but with some luck for you, that'll be me who has to do the retrofitting :3

@Amanieu
Copy link
Member

Amanieu commented Nov 5, 2024

We discussed this in the libs-api meeting today and we're happy with this as proposed. Support for multiple stable attribute was somewhat controversial but in the end we felt that it would be useful in macros which apply a mix of stability attributes to many items.

@Amanieu Amanieu removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Nov 5, 2024
@dianne
Copy link
Contributor Author

dianne commented Nov 5, 2024

Whoever happens to merge their changes first will force the other to retrofit their changes onto it haha, but with some luck for you, that'll be me who has to do the retrofitting :3

I've been wondering about this. My one hope if I do the rebase is that the attribute rework will make this cleaner in the end. 😅

We discussed this in the libs-api meeting today and we're happy with this as proposed.

Nice! I'll get to work on documenting it soon.

@jdonszelmann
Copy link
Contributor

It probably will, the reason it's annoying is that in my local version, builtins.rs is simply gone. It's split up into files for all the different attributes that are processed there. So we'll just have to find the parts that have to move, should be doable.

This moves stability structs' `feature` fields into `StabilityLevel::Unstable` and
`ConstStabilityLevel::Unstable`, in preparation to support multiple unstable attributes on items.

Seemingly, the `feature` field isn't used with the `StabilityLevel::Stable` variant, so I haven't
included it. `rustc_passes::lib_features` uses the 'feature' meta-item for 'stable' attributes, but
it extracts them itself, rather than relying on `rustc_attr`.

In order to support the new const stability check rules, this additionally introduces
`ConstStabilityLevel` and moves the case of `feature` being `None` to the `Implicit` variant for
clarity; having it correspond to an empty `unstables` vec seems like it would be a footgun.
…ions

the logic for adding unstable attrs gets a bit messier when supporting multiple
instances thereof. this keeps that from being duplicated in 3 places.
…els" errors

this makes things a little cleaner.
since multiple stability levels are allowed, I think it makes sense too.
An item is unstable if it has any unstable attributes, to make it easier to track which features
library items depended on as they stabilize.

This changes the text for E0544. Unfortunately, the example doesn't make much sense anymore.

The way this merges stability levels together is made to work for stability-checking and rustdoc;
as far as I can tell, only `rustc_passes::lib_features` needs them separate, and it extracts them
itself.
- only emits one error/lint (instead of one per missing feature) per usage of unstable and
  body-unstable items
- only emits one future-name-collision lint (instead of one per missing feature) for unstable trait
  items
- makes diagnostics for unstable, soft-unstable, const-unstable, and body-unstable library features
  translatable, using common subdiagnostic structs.
- adds notes with features, reasons, and issue links to const-unstability errors
- adds notes with issue links to soft_unstable lints
- on nightly, adds `#![feature]` crate attr help to soft_unstable lints
- on nightly, adds compiler-upgrade-suggestion notes to const-unstable and soft_unstable diagnostics
Reasons provided on `#[unstable]` attributes are now per-item rather than
per-feature. This is how they mostly are used anyway, and it simplifies both
the implementation and the diagnostics themselves.
It doesn't make sense for something to be partially soft, and allowing inconsistent softness
markers would risk an item accidentally becoming properly unstable as its features stabilize.
On nightly, there's a suggestion/help containing the `#![feature(..)]`
attribute required to enable any required unstable features, so the note
listing the features is unnecessary. This only applies to const-unstable
and default-body-unstable errors. Normal "use of unstable library
feature" errors list the features in the error message, so it doesn't
feel redundant.
@rustbot
Copy link
Collaborator

rustbot commented Nov 6, 2024

Some changes occurred to the CTFE machinery

cc @rust-lang/wg-const-eval

@dianne
Copy link
Contributor Author

dianne commented Nov 6, 2024

Is that a new notification? Unless I made a mistake, I think all I did was resolve the merge conflict straightforwardly, so see the above discussion for how this touches the CTFE machinery.

@RalfJung
Copy link
Member

RalfJung commented Nov 6, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. 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.

Allow multiple #[unstable] attributes on one item
8 participants