Skip to content

Libs proposal: Policy for constifying traits and trait implementations #155816

@tgross35

Description

@tgross35

Context

For the past ~year we have been getting a number PRs that constify traits or their implementations. It seems like a number of these aren't intended with any specific goal other than completeness. There are a few concerns about this that I and other reviewers have brought up:

  1. A complete unstably constified standard library isn't necessary for proving out const traits, yet many PRs seem to be aiming for this.
  2. Syntax changes before the RFC is accepted would cause churn (not the most concerning).
  3. Semantic changes to the RFC are less likely but still possible. Hopefully we won't need to worry about this; however, it is entirely possible for a logic change to mean we need to re-review or possibly remove every impl accepted thus far.
  4. Similar to the above: any necessary change or removal while const traits are unstable would have a ripple effect, which compounds with more dependent impls.
  5. This constification process can introduce less maintainable code. We have had real bugs from this.
  6. Constifications always introduces restrictions in how library code can be changed. There are also non-obvious interactions, such as Implement const Deref{,Mut} for String #155640 (comment).
  7. Our review bandwidth is limited right now. The cost per additional const impl is often small but does add up, and any future changes will have a cost as well.

In short, it feels like we are acquiring tech debt with not enough payoff at this time. For an idea of scale, a simple rg shows we currently have at least 76 const traits, 773 const impls, and 29 const_derives. That's already a lot of API!

To help mitigate this, it would be nice if we had a more clear policy about what we do and don't want to constify for now.

Proposed Guidelines

  1. The main driver of what to constify should be needs within rust-lang. That is:
    1. Constifications needed to test new aspects of const traits or other lang features are completely fine. Examples: const iterators, const closures, sized hierarchy work, patterns, const heap, lang item traits requiring const methods, etc.
    2. Small constifications that make it easier to write standard library code are fine (caveats below).
    3. Giving nightly users more const API is not sufficient reason to constify a trait or impl at this time, nor is checking off impls from a list. †
  2. Standard library code should still generally not be written or rewritten using const traits†. Examples to avoid: for->while, more as casts, potentially anything FIXME(const-hack), anything that relies on a "deep" const trait chain (to avoid the ripple effect of changes).
  3. Avoid adding const traits/impls in alloc or std. The usefulness of these crates in const contexts is more fundamentally limited than by traits.
  4. When in doubt, link users to this issue and decline the trait-related constifications.†
  5. These are guidelines; there will be exceptions. Rules for const trait are more lax than for impl const.

All aspects marked with † are things that we could consider relaxing once there is an accepted const trait RFC.

I would like to reiterate that the goal here is not to limit experimentation, but rather to give library maintainers a handle on how widely and deeply the standard library is tied to const traits while still under design. We can revisit these guidelines once there is an RFC, and remove them completely once const traits are stable.

Cc @rust-lang/wg-const-eval
Cc @rust-lang/project-const-traits

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.I-libs-nominatedNominated for discussion during a libs team meeting.PG-const-traitsProject group: Const traitsT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions